双重循环,枚举每个数,O(n^2)
分治,我们来找答案的区间:假设答案在[left,right]这个数的区间里,那么根据抽屉原理,整个数在[left,right]中的个数一定大于
right-left+1, 因为答案出现了两次。根据这个原理,我们每次可以将搜索的数的范围砍掉一半,因此最终的时间复杂度是O(nlogn)
class Solution {
public:
int findDuplicate(vector<int>& nums) {
// 枚举数的范围
int left = 1, right = nums.size()-1;
while(left<=right){
int mid = (left+right)/2;
if(check(nums,mid,right)) left = mid+1;
else right = mid-1;
}
return right;
}
bool check(vector<int>& nums, int left, int right){
int count = 0;
for(auto num:nums){
if(num>=left&&num<=right) count++;
}
return count>right-left+1;
}
};