[LeedCode]Find the Duplicate Number/Linked List Cycle II

看到一個時間複雜度爲O(n)的解法,覺得很有意思。記錄一下。

題目:
Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.

Note:
You must not modify the array (assume the array is read only).
You must use only constant, O(1) extra space.
Your runtime complexity should be less than O(n2).
There is only one duplicate number in the array, but it could be repeated more than once.
Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.

Subscribe to see which companies asked this question.

O(n)時間複雜度代碼:

public class Solution {
    public int findDuplicate(int[] nums) {
        int slow = 0;
        int fast = 0;
        int finder = 0;

        while (true){
            slow = nums[slow];
            fast = nums[nums[fast]];
            if (slow == fast)
                break;
        }
        while (true)
        {
            finder = nums[finder];
            slow = nums[slow];
            if (slow == finder)
                return slow;
        }
    }
}

解析:
解析引用自@LuckyPants said in Share my solution O(N) time O(1) space. 12 ms:
來源:https://discuss.leetcode.com/topic/29716/share-my-solution-o-n-time-o-1-space-12-ms/16
這裏寫圖片描述

k 是進入循環前的長度,
c 是循環的長度
A 是循環入口

從slow和fast開始移動到他們相遇,設slow走過的距離爲X
fast走過的距離爲2X,相遇時有X = 2X - X = n*c .
(ps: n是一個正整數且易知 n*c >= k)

n*c - k = 相遇時過A點距離
所以slow和fast相遇時位置和A入口的距離應爲(n*c - k)%c

爲了從當前位置再次到達A點,即(n*c - k + k)%c = 0
我們用一個從0開始的finder,以和slow一樣的速度到達A,距離爲k,slow也走這樣長的距離,因而得到入口點A。

圓的入口不止一個,這意味着至少兩個數字不同的索引數組中有相同的值,slow和finder索引記錄的就是重複的數字。


同樣原理的應用:Linked List Cycle II

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?

Subscribe to see which companies asked this question.

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {

        if (head == null||head.next==null || head.next.next==null) return null;
        ListNode slow = head.next;
        ListNode fast = head.next.next;
        ListNode k = head;

        while (slow!=fast)
        {
            if(fast.next==null || fast.next.next==null)
                return null;
            slow = slow.next;
            fast = fast.next.next;
        }
        while (k!=slow)
        {
            k = k.next;
            slow = slow.next;
        }
        return k;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章