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

LeetCode 287 Find the Duplicate Number

287. Find the Duplicate Number

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.

Example 1:

Input: [1,3,4,2,2] Output: 2 Example 2:

Input: [3,1,3,4,2] Output: 3 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.

給定一個包含 n + 1 個整數的陣列 nums,其數字都在 1 到 n 之間(包括 1 和 n),可知至少存在一個重複的整數。假設只有一個重複的整數,找出這個重複的數。

示例 1:

輸入: [1,3,4,2,2] 輸出: 2 示例 2:

輸入: [3,1,3,4,2] 輸出: 3 說明:

不能更改原陣列(假設陣列是隻讀的)。 只能使用額外的 O(1) 的空間。 時間複雜度小於 O(n2) 。 陣列中只有一個重複的數字,但它可能不止重複出現一次。

【思路1】剛看到這道題,找相同資料的時候,立馬想到了hashMap.hashMap.cotainKey的時間複雜度為o(1),但是不符合題目的要求,只能使用額外的O(1)空間。因此繼續摳題目。後來和學長請教,發現一種精妙無比的演算法。我們的想法,就是遍歷一遍陣列,每當出現一個數時,將其當作下邊,並將nums中對應下標的數進行修改,如何才能修改完之後仍然能看出原有資料呢?答案就是將其加上nums.length,每找到一個就加上nums.length。如果我們發現nums的值大於兩倍nums.Length時,找到該值。

【程式碼】

public class Solution2 {
	public int findDuplicate(int[] nums) {
		int nums_len = nums.length;
		for(int n:nums){
			if (n > nums_len) //說明這個下標的數已經找到,其真實資料為n-nums_len
				if (nums[n-nums_len - 1] > nums_len) return n-nums_len;
				else nums[n-nums_len - 1] += nums_len;
			else 
				if(nums[n - 1] > nums_len) return n;
				else nums[n - 1] += nums_len;
				
		}
		return 0;
	}
}