287. 寻找重复数
二分
二分并不是在nums
数组上进行的,二分是在1 2 3 4 ... n
上搜索的
cnt[i]
表示比<=i
的数有多少个
这里的cnt
数组没必要都算出来。每次计算当前<=mid
的cnt就行了。
- 问题、对比
这个返回l
还要再思考思考,这个二分模板是l<=r
为判断条件,yxc的是l<r
为判断条件,这样返回l
和r
对应的值都一样了。 - 分析、解决
当最后要退出的时候:l=r=mid
,这一次找的mid
就是答案了,一定不会执行cnt<=mid
的内容,而是r=mid-1
的内容,这时候就是r+1=l=mid
了,所以返回l
是对的 - 反推、泛化
所以当l<=r
为条件的时候,看里面的if l=mid+1
和else r=mid-1
哪个一定不会执行,才能判断最后l
是对的位置还是r
是对的位置
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int l=1,r=nums.size()-1;
while(l<=r){
int mid=l+r>>1;
int cnt=0;
for(auto i:nums)cnt+=i<=mid;
if(cnt<=mid) l=mid+1;
else r=mid-1;
}
return l;
}
};