[LeetCode]142.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?

分析:

首先使用快慢指针技巧,如果fast指针和slow指针相遇,则说明链表存在环路。当fast与slow相遇时,slow肯定没有遍历完链表,而fast已经在环内循环了n圈了(1<=n)设slow走了s步,则fast走了2s步(fast步数还等于s加上环在多转的n圈),设环长为r则:

                    2s = s + nr
                    s = nr

设整个链长L,环入口点与相遇点距离为a,起点到环入口点距离为x,则:

             x + a = s = nr = (n - 1)r + r = (n - 1)r + L - x
             x = (n - 1)r + L - x - a

L -x -a 为相遇点到环入口点的距离,由此可知,从链表开头到环入口点等于n - 1圈内环 + 相遇点到环入口点,于是我们可以从head开始另设一个指针slow2,两个慢指针每次前进一步,他们两个一定会在环入口点相遇。

代码:

    /**------------------------------------
    *   日期:2015-02-05
    *   作者:SJF0115
    *   题目: 142.Linked List Cycle II
    *   网址:https://oj.leetcode.com/problems/linked-list-cycle-ii/
    *   结果:AC
    *   来源:LeetCode
    *   博客:
    ---------------------------------------**/
    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;

    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;
            }//if
            ListNode *slow = head,*fast = head,*slow2 = head;
            while(fast != nullptr && fast->next != nullptr){
                slow = slow->next;
                fast = fast->next->next;
                // 相遇点
                if(slow == fast){
                    while(slow != slow2){
                        slow = slow->next;
                        slow2 = slow2->next;
                    }//while
                    return slow;
                }//if
            }//while
            return nullptr;
        }
    };

时间: 2024-10-02 13:41:57

[LeetCode]142.Linked List Cycle II的相关文章

[LeetCode 第11题] -- Linked List Cycle II

题目链接: Linked List Cycle II 题目意思: 给定一个链表,如果链表有环求出环的起点,否则返回NULL 解题思路:      1. 判断链表是否有环: 两个指针,一个一次走一步,一个一次走两步,如果指针相遇说明有环,否则无环.     2. 如果有环的情况下,我们可以画个图(图片来自网络)                   假设两个指针在z点相遇.则          a. 指针1走过路程为a + b:指针2走过的路程为 a+b+c+b          b. 因为指针2的

[LeetCode]141.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? [题意] 给定一个链表,确定它是否包含一个环. [分析] 最容易想到的方法是,用一个哈希表 unordered_map<int, bool> visited,记录每个元素是否被访问过,一旦出现某个元素被重复访问,说明存在环. 空间复杂度 O(n),时间复杂度 O(N

[LeetCode] 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? 解题思路 设链表长度为n,头结点与循环节点之间的长度为k.定义两个指针slow和fast,slow每次走一步,fast每次走两步.当两个指针相遇时,有: fast = slow * 2 fast -

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? 本来不是很难的一题,提交了n遍,一直运行时错误,为什么呢?因为一个指针判断的问题,由于要向后移动两个指针,因为p->next也需要判断,而不能仅仅判断p,不然p=p->next->next会有

[LeetCode 第10题] -- Linked List Cycle

题目链接: linked List Cycle 题目意思: 给定一个链表,判断链表是否有环 代码: /** * 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); }; b

[LeetCode] Split Linked List in Parts 拆分链表成部分

Given a (singly) linked list with head node root, write a function to split the linked list into k consecutive linked list "parts". The length of each part should be as equal as possible: no two parts should have a size differing by more than 1.

[LeetCode] 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? 解题思路 使用快慢两个指针,如果快的指针赶上了慢的,则说明存在回路. 实现代码 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNod

[LeetCode] Reverse Linked List II

Reverse a linked list from position m to n. Do it in-place and in one-pass. For example: Given 1->2->3->4->5->NULL, m = 2 and n = 4, return 1->4->3->2->5->NULL. Note: Given m, n satisfy the following condition: 1 ≤ m ≤ n ≤ le

[LeetCode] Reverse Linked List(递归与非递归反转链表)

Reverse a singly linked list. 解题思路 对于非递归实现,思路是依次将从第二个结点到最后一个结点的后继设为头结点,然后将该节点设为头结点(需记住将原头结点的后继设为空). 对于递归实现,首先反转从第二个结点到最后一个结点的链表,然后再将头结点放到已反转链表的最后,函数返回新链表的头结点. 非递归实现代码1[C++] //Runtime:10 ms class Solution { public: ListNode* reverseList(ListNode* head