LeetCode刷题:Linked List Cycle 及其进阶Linked List Cycle II

Given a linked list, determine if it has a cycle in it.

Follow up:
Can you solve it without using extra space?

1. 首先解决的问题是 判断单链表 有没有环?

解题思路:

两个指针slow 和 fast,开始都指向 head, slow指针每次走一步,fast 指针每次走两步,看看最终 slow 和 fast 会不会重合,如果 链表有环,那么一定会重合。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) 
    {
        if(head == NULL || head->next == NULL)
        {
            return false;
        }
        
        ListNode *slow, *fast;
        slow = fast = head;
        
        //fast = fast->next;
        
        while( fast != NULL && fast->next != NULL)
        {
            fast = fast->next;
            if (slow == fast)
            {
                return true;
            }
            slow = slow->next;
            fast = fast->next;
        }
        
        
        if(fast == NULL || fast->next == NULL)
        {
            return false;
        }
        else
        {
            return false;
        }
    }
};

2. 问题进阶: 如果链表有环,返回环开始的那个节点, 该怎么做呢?

LeetCode 上的问题:

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Note: Do not modify the linked list.

Follow up:
Can you solve it without using extra space?

引用网上的一张图:


image


Like the picture shows above: assume linked list has cycle,the length of cycle is Y,the length outside cycle is X. 

Two pointers, one goes one step per time, another goes two steps per time. If they went t times and meet at the K node.

ponter 1 每次走一步,pointer 2 每次走两步, 下面公式中的t 代表每个pointer总的路程:

for pointer 1: t = X+nY+K

for pointer 2: 2t = X+mY+K (m,n is unknown)

From above equation, we could get:

2X + 2nY + 2K = X + mY + K

=>   X+K  =  (m-2n)Y 


所以 X+K 等于 Y 的整数倍。

所以有下面的结论(数学问题,我还是不太能理解):

It is clear that the relationship between X and K is complementary based on Y. 

Which is to say, if pointer 1 goes X steps from start node and pointer 2 goes X steps form K node. They will meet at the start place of cycle. 

Complexity is O(n)

反正就是: pointer 1 和 pointer 2 找到重合点K 后,那么 pinter 1 返回起点head, pointer 2 从K处继续走,他们一定会在环的起始点相遇。

这个我试了几组,确实是这样的。


代码如下:


/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        //if(head == NULL || head->next == NULL)
        //{
        //    return NULL;
        //}
        
        ListNode *slow, *fast;
        slow = fast = head;
        //fast = fast->next;
        
        while(fast!=NULL && fast->next !=NULL)
        {
            slow = slow->next;
            fast = fast->next->next;
            if(slow == fast)
            {
                break;
            }
            //fast = fast->next;
        }
        
        if (fast == NULL || fast->next == NULL)
        {
            return NULL;
        }
        
        //has cycles, so find the cycle start point.
        slow = head;
        if(slow->next == fast)
        {
            return slow;
        }
        while(slow != fast)
        {
            slow = slow->next;
            fast = fast->next;
        }
        return slow;
    }
};



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值