您的位置:首页 > 其它

287. Find the Duplicate Number

2016-05-10 15:07 495 查看
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.

加入忽略题目对时间复杂度(less than O(N^2))和空间复杂度(O(1))的要求,可以想到有以下几种方法:

(1)直接搜索法

时间复杂度O(N^2),空间复杂度O(1).
针对每个元素,向后寻找是否存在其重复元素。

(2)哈希表法

时间复杂度O(N),空间复杂度O(N).

用一个集合/map记录已经遍历过的数,如果已经有了说明是重复数字。(集合中元素不可重复,map中key不可重复)

public int findDuplicate(int[] nums){
Map<Integer,Integer> myMap = new HashMap<Integer,Integer>();
//Set<Integer> mySet = new HashSet<Integer>();
for(int num:nums){
if(myMap.containsKey(num)) return num;
myMap.put(num, 1);
/*
* if(mySet.contains(num)) return num;
* mySet.add(num);
*/
}
return 0;
}


(3)排序法

时间复杂度O(N*logN),空间复杂度O(1)/O(N). (如果不复制数组,则空间复杂度为O(1),但是排序时会改变原数组;复制数组则空间复杂度为O(N)).

public int findDuplicateBySort(int[] nums){
Arrays.sort(nums);
for(int i=1;i<nums.length;i++){
if(nums[i] == nums[i-1]) return nums[i];
}
return 0;
}
public int findDuplicateBySortAndCopy(int[] nums){
        int[] newArr = Arrays.copyOf(nums, nums.length);
        Arrays.sort(newArr);
        for(int i=1;i<nums.length;i++){
            if(newArr[i] == newArr[i-1]) return newArr[i];
        }
        return 0;
    }


然后看了网上的一些参考答案,寻找到一些符合题目要求的算法:

(1)二分法

由于这n+1个数字介于1~n之间,首先用二分法选择n/2作为比较对象,当整个数组中小于等于n/2的数字超过n/2,说明1~n/2之间肯定有重复数字,否则n/2~n之间肯定有重复数字,下次在有重复数字的区间内再次使用二分法。

public class Solution {
public int findDuplicate(int[] nums) {
int min = 0, max = nums.length-1;
while(min<=max){
int mid = (max-min)/2+min;
int count = 0;
for(int i=0;i<nums.length;i++)
if(nums[i]<=mid) count++;
if(count<=mid)
min = mid+1;//后半部分有重复
else max = mid-1; //前半部分有重复
}

return min;
}
}
(2)寻找环路法

元素index和元素本身之间存在一个映射关系,从下标0开始,可以产生一个类似链表的序列,如果存在重复元素,则会出现环路,我们就是要寻找环路的起点。
https://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare
有时间多看看==
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: