Skip to content

Latest commit

 

History

History
58 lines (49 loc) · 1.87 KB

File metadata and controls

58 lines (49 loc) · 1.87 KB

题目:给出包含n+1个元素的数组,所有数字都在1~n范围内,找出数组中冗余的数组

  • 不能修改数组
  • 要求O(1)的空间复杂度
  • 时间复杂度要小于O(n^2)
  • 只有1个元素冗余,但是可能冗余很多次

思路:假设1~n的中间元素是mid,遍历数组:

  • 如果小于等于mid的个数大于mid,说明重复数字出现在1~mid中
  • 如果小于等于mid的个数小于等于mid,说明重复数组出现在mid+1~n中

每轮需要遍历n+1个元素,但是每次可以将范围缩小一半,因此时间复杂度小于O(n^2)

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int l = 1,r = nums.size() - 1;//l和r初始化成1和n
        while(l < r){
            int mid = (l + r) >> 1;
            int count = 0;//小于等于mid的数的个数
            for(int i = 0;i < nums.size();i++)
                if(nums[i] <= mid)   count++;
            if(count <= mid)
                l = mid + 1;
            else if(count > mid)
                r = mid;
        }
        
        return l;
    }
};

去掉一个条件,如果可以修改数组,那么遍历数组中的每个数num,如果num不等于当前下标加1。那么将这个数与下标为num - 1的数交换,直到num等于当前下标加1。如果num - 1位置的数和num相等,表示出现重复,因此返回num

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        for(int i = 0;i < nums.size();i++){
            int tp;
            while(nums[i] != i + 1){
                if(nums[nums[i] - 1] != nums[i]){
                    tp = nums[nums[i] - 1];
                    nums[nums[i] - 1] = nums[i];
                    nums[i] = tp;
                }
                else
                    return nums[i];
            }
        }
        
        return -1;//输入数据无效
    }
};