【LeetCode】【C++】Linked list cycle 2

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?

此题不难,但想不用extra space做出来还是要动点脑筋的,因为我之前看过类似的算法题,所以就很快想到了。

方法是利用两个指针从头开始,指针p1一次走一步,指针p2一次走两步,如果有环则两指针必定有重逢之时(这是Linked List Cycle里用到的)。

然后就是如何求出环的起始节点。

可以这么假定,从链的起点到环的起点,这段距离称为a。环的长度称为c,第一次相遇位置距环的起点距离为p。首先p1被p2追上时它一定没有走完整个环(想想为什么?)也就是说0<p<c.所以从出发到相遇,p1走过的距离为a+p,p2走过的距离为a+p+nc(n为正整数)。又因为p2速度为p1两倍,所以有

2a+2p=a+p+nc,所以有a+p=nc。现在两指针均处在环起点过p的位置上,再走a个距离即可回到环的起点。而a恰好是链的起点到环的起点的距离,所以我们另其中一指针回到链的起点,另一指针仍在原地,同时以速度1前进,再次相遇一定是在环的起点了。

/**
 * 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) {
        ListNode *p1=head;
        ListNode *p2=head;

        bool hasCycle = false;
        if (!head) return NULL;
        while(p2->next!=NULL){
            p1 = p1->next;
            p2 = p2->next->next;
            if (p2 == NULL) return NULL;
            if (p1 == p2){
                hasCircle = true;
                break;
            }
        }
        if (!hasCycle) return NULL;
        else{
            p2 = head;
            while (p1!=p2){
                p1 = p1->next;
                p2 = p2->next;
            }
            return p1;
        }

    }
};
时间: 2024-11-05 03:06:13

【LeetCode】【C++】Linked list cycle 2的相关文章

【leetcode刷题笔记】Flatten Binary Tree to Linked List

Given a binary tree, flatten it to a linked list in-place. For example,Given 1 / 2 5 / \ 3 4 6 The flattened tree should look like: 1 2 3 4 5 6 Hints: If you notice carefully in the flattened tree, each node's right child points to the next node of a

【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? 判断一个链表是否有环. 题解: 设置两个指针p1和p2: p1每次走一步,p2每次走两步,如果在这个过程中,p2为空,则没有环:否则两个指针必然相遇,则有环: 接下来找环的起点,将p1挪动到链表起始,

【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 ≤ lengt

【leetcode刷题笔记】Insertion Sort List

Sort a linked list using insertion sort. 题解:实现链表的插入排序. 要注意的地方就是,处理链表插入的时候尽量往当前游标的后面插入,而不要往前面插入,后者非常麻烦.所以每次利用kepeler.next.val和head.val比较大小,而不是kepeler.val和head.val比较大小,因为如果用后者,要把head指向的节点插入到kepeler指向的节点的前面,如果kepeler指向的节点是头结点,就更麻烦了. 代码如下: 1 /** 2 * Defi

【leetcode刷题笔记】Sort List

Sort a linked list in O(n log n) time using constant space complexity. 题解:实现一个链表的归并排序即可.主要分为三部分: 1.找到中点并返回的函数findMiddle; 2.归并函数merge; 3.排序函数sortList. 数组的findMiddle函数非常容易实现,链表就有一点tricky了.首先设置两个指针,一个slow初始化为head,一个fast初始化为head.next,然后slow一次走一步,fast一次走两

【leetcode刷题笔记】Add Two Numbers

You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. Input: (2 -> 4 -> 3) + (5 -> 6 ->

【leetcode刷题笔记】Remove Duplicates from Sorted List

Given a sorted linked list, delete all duplicates such that each element appear only once. For example,Given 1->1->2, return 1->2.Given 1->1->2->3->3, return 1->2->3. 题解:水题不解释 1 /** 2 * Definition for singly-linked list. 3 * str

【leetcode刷题笔记】Remove Duplicates from Sorted List II

Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. For example,Given 1->2->3->3->4->4->5, return 1->2->5.Given 1->1->1->2->3, return 2->3.

【leetcode刷题笔记】Remove Nth Node From End of List

Given a linked list, remove the nth node from the end of list and return its head. For example, Given linked list: 1->2->3->4->5, and n = 2. After removing the second node from the end, the linked list becomes 1->2->3->5. Note:Given n

【leetcode刷题笔记】Merge k Sorted Lists

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 题解:最开始用了最naive的方法,每次在k个链表头中找出最小的元素,插入到新链表中.结果果断TLE了. 分析一下,如果这样做,每取出一个节点,要遍历k个链表一次,假设k个链表一共有n个节点,那么就需要O(nk)的时间复杂度. 参考网上的代码,找到了用最小堆的方法.维护一个大小为k的最小堆,存放当前k