Leetcode刷题——环形链表II

大家好,继续刷题,这次一道找环形链表入环点的题,看下题目要求:

思路:1.我看了剑指offer上对这道题的解读,首先是快慢指针判断是否有环,针对快慢指针的方法参考我的这一篇博客

点击打开新世界的大门

判断完以后,设置一个指针temp指向相遇点并原地循环一周,再次回到快慢指针相遇的这个结点时算出这个环总共包含多少结点,结点数设为n。然后让快慢指针都回到head,再让快指针提前走n步,然后快慢指针同时每次走一步,相遇的结点即为入环结点。

如图,链表的总长度为a + n,fast提前走了n,当fast和slow共同走了a步时,slow走到入环结点,fast走了一整个链表的长度因此走到了链表的尾部,也是入环结点处,因此此时fast和slow相遇了。代码如下:

/**
 * 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 == nullptr)
            return nullptr;
        ListNode * slow = head;
        ListNode * fast = head;
        ListNode * temp = nullptr;
        int node = 1;
        while(fast -> next != nullptr){
            slow = slow -> next;
            fast = fast -> next;
            if(fast -> next != nullptr)
                fast = fast -> next;
            else return nullptr;
            if(slow == fast){
                temp = slow;
                break;
            }
        }
        if(temp != nullptr){
            while(temp -> next != slow){
                temp = temp -> next;
                node++;
            }
            slow = head;
            fast = head;
            for(int i = 0;i < node;i++){
                fast = fast -> next;
            }
            while(slow != fast){
                slow = slow -> next;
                fast = fast -> next;
            }
            return slow;
        }
        else return nullptr;
    }
};

这种方法虽然挺好的,但是在leetcode里跑会超时。

2.第二种方法也是先用快慢指针判断是否有环,然后如上图所示,相遇点到入环结点的距离为b。可以看到在相遇时fast走的路径是slow的两倍,由此可以推算出a = c。所以在两指针相遇后只让slow回到head,然后slow和fast每次各走一步,当fast走了c时slow走了a,两指针再次相遇,此时就是入环结点。代码如下:

/**
 * 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 == nullptr)
            return nullptr;
        ListNode * slow = head;
        ListNode * fast = head;
        ListNode * temp = nullptr;
        int node = 1;
        while(fast -> next != nullptr){
            slow = slow -> next;
            fast = fast -> next;
            if(fast -> next != nullptr)
                fast = fast -> next;
            else return nullptr;
            if(slow == fast){
                temp = slow;
                break;
            }
        }
        if(temp != nullptr){
            slow = head;
            while(slow != fast){
                slow = slow -> next;
                fast = fast -> next;
            }
            return slow;
        }
        else return nullptr;
    }
};

好了,我们下期见!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值