1. (环)Linked List Cycle
Given a linked list, determine if it has a cycle in it.
Follow up: Can you solve it without using extra space?
//快慢指针
bool hasCycle(ListNode *head){
ListNode *slow = head;
ListNode *fast = head;
while (fast && fast->next){
slow = slow->next;
fast = fast->next->next;
if (fast==slow) return true;
}
return false;
}
2. Linked List Cycle II
Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
Follow up: Can you solve it without using extra space?
ListNode *detectCycle(ListNode *head){
ListNode *slow = head;
ListNode *fast = head;
while (fast && fast->next){
slow = slow->next;
fast = fast->next->next;
if (fast==slow) break;
}
if (fast == NULL || fast->next == NULL)
return NULL;
slow = head;
while(fast!=slow){
slow = slow->next;
fast = fast->next;
}
return fast;
}
3. 公共结点
(阿里2014实习生笔试)两个较长的单向链表a和b,为了找出单node满足node in a并且node in b。请设计空间使用尽量小的算法(用c/c++,java 或者伪代码)。
分析:时间复杂度为O(m+n),空间复杂度为O(1),不需要辅助栈
//算法的空间复杂度O(1),时间复杂度O(m+n)
struct node {
int v;
node *next;
};
//返回链表的长度 链表为空 返回0
size_t listLen(node *p)
{
size_t num = 0;
while (p!=NULL) {
num++;
p = p->next;
}
return num;
}
// 如果找到了 则返回指针 指向公共节点
// 如果不存在 则返回空指针
node * findFirstCommenNode(node * pheada, node * pheadb)
{
size_t lenA = listLen(pheada);
size_t lenB = listLen(pheadb);
node * plistA = pheada;
node * plistB = pheadb;
//调整长度 , plistA 指向较长的一个
if (lenA < lenB)
{
plistB = pheada;
plistA = pheadb;
size_t t = lenA;
lenA = lenB;
lenB = t;
}
while(lenA > lenB)
{
plistA = plistA->next;
--lenA;
}
//一样长了 寻找公共节点
while (plistA!=NULL && plistA != plistB)
{
plistA = plistA->next;
plistB = plistB->next;
}
return plistA;
}
4. 链表中倒数第K个结点
快慢指针,快指针先走K-1步。
需要注意k的值大于链表长度的情况。时间复杂度为O(N)。
ListNode* FindKthToTail(ListNode* pHead,unsigned int k){
if(pHead == NULL || k ==0)
return NULL;
ListNode* pFast = pHead;
ListNode* pSlow = NULL;
for(unsigned int i = 0;i<k-1;++i){
if(pFast->next != NULL)
pFast = pFast->next;
else
return NULL;
}
pSlow = pHead;
while(pFast->next != NULL){
pFast = pFast->next;
pSlow = pSlow->next;
}
return pSlow;
}
5. 求链表的中间结点
如果链表中结点总数为奇数,返回中间结点;为偶数,返回中间两个结点中的任意一个。
快慢指针。快指针一次走两步,满指针一次走一步。