1. 程式人生 > >[LeetCode] 287. Find the Duplicate Number

[LeetCode] 287. Find the Duplicate Number

etc int 一個數 空間 ont slow i++ for clu

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.

給一個數組,其中一定有且只有一個數字是重復的,找出那個數字;

O(n2)的算法就不說了

法一 O(n)空間 O(n)時間,開一個set直接記錄

class
Solution { public int findDuplicate(int[] nums) { Set<Integer> set = new HashSet<>(); for (int i = 0; i < nums.length; i++) { if (set.contains(nums[i])) return nums[i]; else set.add(nums[i]); }
return -1; } }

法二 先排序再找 時間O(nlogn) 空間O(1)

class Solution {
    public int findDuplicate(int[] nums) {
        Arrays.sort(nums);
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] == nums[i - 1])
                return nums[i];
        }
        return -1;
    }
}

法三,把這個數組看成列表

因為裏面的元素是小於n的,所以可以這麽做

比方說數組是 1 3 2 3 4 那麽

下標就是 0 1 2 3 4

那麽 讓其元素連接下標 使之構成鏈表,那麽其中一定存在環,就可以用142. Linked List Cycle II那個算法了()

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

        while (slow != fast) {
            slow = nums[slow];
            fast = nums[nums[fast]];
        }
        slow = 0;
        while (slow != fast) {
            slow = nums[slow];
            fast = nums[fast];
        }
        return slow;
    }
}

補充:這題還有一個O(nlogn)的解法,就是利用二分法,我不推薦用這個解法,因為大多數人用二分法時都會因為邊界問題而出錯

這個算法裏要反復使用二分,說來慚愧,我二分也常常出錯,所以就不丟人,有興趣的同學可以去查一下

[LeetCode] 287. Find the Duplicate Number