287. Find the Duplicate Number

来源:互联网 发布:java连接ssh的jar包 编辑:程序博客网 时间:2024/06/16 06:03

1.题目
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.

2.分析
这是使用查找重复数来考察数组这个存储数据对象,数组是给定长度,并可以存储一般类型与对象的对象类型。这道题其实本身并不是很难,难的是它的限制条件,只能使用常数范围内的辅助空间,且时间复杂度要小于O(n^2),当时我因为这个限制条件,思考蛮久,没有下手,如果没有这些限制条件,使用双层循环或者利用Map/Set的特性就可以很好的解决问题。

3.解题
我的解法

public class Solution {public int findDuplicate(int[] nums) {    // 边界处理    if(nums==null||nums.length==0){        return 0;    }    int result = nums[0];    for(int i=0;i<nums.length;i++){        for(int j=0;j<i;j++){            if(nums[j]==nums[i]){                result = nums[j];                break;            }        }    }    return result;}}

别人的解法一:

public int findDuplicate(int[] nums) {int left = 0, right = nums.length - 1;while(left <= right) {    int mid = left + (right - left) / 2;    int cnt = 0;    for(int i = 0; i < nums.length; i ++) {        if(nums[i] <= mid) cnt ++;    }    if(cnt > mid) right = mid - 1;    else left = mid + 1;}return left;}

别人的解法二:

public int findDuplicate(int[] nums) {if(nums.length > 1) {    int slow = 0;    int fast = 0;    while(true) {       slow = nums[slow];       fast = nums[nums[fast]];       if(slow == fast) {           // case like [1,2,3,1]           // 把一个指针放回到开头的地方           slow = 0;           while(slow != fast) {               slow = nums[slow];               fast = nums[fast];           }           return slow;       }    }}return -1;}

4.总结
  我的解法当时想的是采用双层for循环,但是在循环里面做优化,就是尽量减去很多不必要的步骤,于是我想到得是第一层for循环的下标作为第二层for循环的下标边界,这样就避免了每次遍历都需要进行O(n)的遍历,很像优化后的冒泡排序,当然我这样做其实最坏的情况下时间复杂度也是O(n^2),但是平均时间消耗还是小于O(n^2)的。然后别人的解法一,没有什么好说的,就是利用了二分查找的思想,这样下来,每一步的时间消耗减半,走下了最后时间消耗就是log(n)。其实解法二我也可以理解,使用的就是链表中找环的思想,只是,我现在还没搞明白的是他怎么确保最后的结果是正确的输出结果,就是外层while循环相等的情况下得出的是什么,内存循环当然得出的是结果,但是我还是需要好好想想- -。

原创粉丝点击