一.判断该链表是否有环(简单):
1.题目
2.思路:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
bool hasCycle(struct ListNode *head) {
struct ListNode* slow = head,*fast = head;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if(fast == slow)
{
return true;
}
}
return false;
}
3.扩展问题:
(1) 为什么一定会相遇?有没有可能错过,永远追不上?
(2) 快指针一次走3步,走四步,...n步,能追上吗?
简单分析一下快指针走三步的情况:
(3)上述是我们理论猜想出来的结果,但是实际真的存在永远追不上的情况吗?
分析:
重新总结:
二.环形链表2
1.题目
2.思路1:
我们对指针运动进行数学分析最终得到了头结点到入环节点的距离L与环形链表的关系。
分析代数式,我们得到启发:
注意:
3.参考代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode* slow = head,*fast = head;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if(fast == slow)
{
struct ListNode* meet = fast;
while(head != meet)//指针相交时的位置就是入环位置
{
head = head->next;
meet = meet->next;
}
return meet;
}
}
return NULL;
}
4.思路二
创建一个新指针newhead,指向meet的next指针,再将meet的next置为NULL。这样就变成了我们所熟悉的相交链表问题。大家可以看我的这篇题解http://t.csdnimg.cn/edNbx
参考代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
//相交链表,如果相交返回相交节点,否则,返回NULL
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
int n1 = 1;
int n2 = 1;
struct ListNode* curA = headA;
struct ListNode* curB = headB;
while(curA->next)
{
curA = curA->next;
++n1;
}
while(curB->next)
{
curB = curB->next;
++n2;
}
if(curA != curB)
{//尾节点不相等就不相交
return NULL;
}
//长的先走差距步,再同时走,第一个相等的就是交点
int num = abs(n1 - n2);
struct ListNode* LongList = headA;
struct ListNode* SortList = headB;
if(n1 < n2)
{
LongList = headB;
SortList = headA;
}
while(num--)
{
LongList = LongList->next;
}
while(LongList != SortList)
{
LongList = LongList->next;
SortList = SortList->next;
}
return LongList;
}
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode* slow = head,*fast = head;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if(fast == slow)
{
struct ListNode* meet = fast;
struct ListNode* newhead = meet->next;
meet->next = NULL;
return getIntersectionNode(newhead,head);
}
}
return NULL;
}