【二分】对于二分的理解——代码随想录以及AcWing
二分在代码随想录以及AcWing当中是不同的,具体可见
代码随想录:
https://github.com/youngyangyang04/leetcode-master/blob/master/problems/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.md
AcWing:
acwing.com/blog/content/31/
代码随想录的题目,试图从一个有序不重复数组当中找一个符合的值,所以,这里是要去找一个值,而不是区间。所以才有循环不变量的思想,具体可直接去看代码随想录当中的思维,就是以左闭右闭区间里面有target以及左闭右开区间里有target两种情况当中选择。这种方法并不适用于找区间中符合的值,如果数组中有重复值,也无法保证找到的一定是最左的还是最右的。
Acwing的题目,是在做PAT的进制的题目当中遇到的,当时希望找区间当中符合条件的最左值,用到了其中第一个模板。总结一下,第一个模板其实适用于找左或者右区间的最左值,而第二个模板只适用于找左区间的最右值。这个区间指的是想要寻找的数位于整个数组的位置,比如数组1到10,如果想找的是大于5的数,那就是右区间,否则就是左区间。
还有一点需要注意的,当left取mid时,mid本身要加1,因为mid肯定是偏左的,这样的话left和right永远无法相遇,不加1就会死循环。
所以本质上这两种方法要解决的问题是完全不同的。第二种方法适用性更强,推荐背yxc的方法。用yxc的方法可以这样子做leetcode题:
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size()-1;
while(left < right) {
int mid = left + right >> 1;
if(nums[mid] >= target) right = mid;
else left = mid +1;
}
if(nums[left] == target) return left;
return -1;
}
};