[Leetcode] 287. Find the Duplicate Number 解题报告

来源:互联网 发布:湖南棋牌app源码 编辑:程序博客网 时间:2024/06/08 13:20

题目

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.

思路

1)理论证明:鸽笼原理,说n个东西放到m个容器中,如果n > m,那么必然有一个容器包含多于一个东西。用反证法证明:假设每个容器里面的东西至多有一个,那么m个容器中的东西至多有m < n个,与一共有n个东西相矛盾,所以假设不成立,鸽笼原理成立。

2)代码实现:由于不允许对数组进行排序,也不允许使用额外的空间,所以少于O(n^2)的时间复杂度的解法的唯一可能性就是二分查找。我们使用二分查找先确定一个中间值mid,然后统计整个数组,看比mid小的数是否比mid多,如果多的话,说明重复的值就在[left, mid - 1]之间,否则就在[mid + 1, right]之间。

代码

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