287. Find the Duplicate Number Java Solutin

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:

  1. You must not modify the array (assume the array is read only).
  2. You must use only constant, O(1) extra space.
  3. Your runtime complexity should be less than O(n2).
  4. 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

 
 1 public class Solution {
 2     public int findDuplicate(int[] nums) {
 3         int low = 0, high = nums.length-1;
 4         int mid = 0;
 5         while(low < high){
 6             mid = (low + high)/2;
 7             int count = 0;
 8             for(int i =0;i<nums.length;i++){
 9                 if(nums[i] <= mid) count++;
10             }
11             if(count <= mid) low = mid + 1;
12             else high = mid;
13         }
14         return low;
15     }
16 }

方法二: 双指针 (转自网络,出处不详。)

如果数组中元素不重复,那么,任意下标i和数组中该下标的值一一对应,如 对于数组 3,4,1,2,有如下对应关系:(注意,值从1~n)

  • 0 – > 2
  • 1  -> 4
  • 2  -> 1
  • 3  -> 3

设这个对应关系的运算函数为f(n) ,那么,我们从下标0出发,每次根据f取出下标i对应的值x,并将这个x作为下一次的下标,直到下标越界。

如3,4,1,2这个数组,那么有 0 – > 2-> 1-> 4

但如果有重复的话,中间就会产生多个映射,如3,4,1,2,3

  • 0 – > 2
  • 1  -> 4
  • 2  -> 1
  • 3  -> 3
  • 4  ->3

继续这么做的话,会发生 0 – > 2-> 1-> 4  -> 3 -> 3->3……

也就是最后一定是那个重复的元素。

这样类似于  leetcode 142 Linked List Cycle II一样,找链表环路的起点,我们先用快慢两个下标都从0开始,快下标每轮运算两次,慢下标每轮运算一次,直到两个下标再次相同。这时候保持快下标位置不变,将慢下标移动到0,接着两个每轮分别运算一次,当这两个下标相遇时,就是环的起点,也就是重复的数。

原因详见  142. Linked List Cycle II

时间复杂度为O(n)

 1 class Solution(object):
 2     def findDuplicate(self, nums):
 3         """
 4         :type nums: List[int]
 5         :rtype: int
 6         """
 7         slow , fast = nums[0] , nums[nums[0]]
 8         while slow != fast:
 9             slow = nums[slow]
10             fast = nums[nums[fast]]
11  
12         slow = 0
13         while slow != fast:
14             slow = nums[slow]
15             fast = nums[fast]
16         return slow
原文地址:https://www.cnblogs.com/guoguolan/p/5395637.html