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?

引用网上的一张图:

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;
    }
};
时间: 2024-07-30 13:40:15

LeetCode刷题:Linked List Cycle 及其进阶Linked List Cycle II的相关文章

【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刷题笔记】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刷题笔记】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 刷题之路 93 Merge k Sorted Lists

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 将k个有序链表合并成一个有序链表. 思路,之前做过两个有序链表的合并操作,对于k个链表,我们最先想到的就是能不能转化为我们熟悉的两个链表的合并,可以我们先将k个链表分为两部分,先对这两部分完成链表的有序合并操作,再对合并得到的两个链表进行合并,这是一个递归性质的描述,采用递归很容易实现这个程序,和数组

【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 刷题之路 76 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. 删除排序链表中重复的节点,删除操作完成后,原链表中的重复节点只保留一个. 思路,遍历链表,如果当前节点和下一个节点重复

【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.