前言
又重温了一遍<肖生客的救赎> 其中安迪的一句话一直回荡我的脑中:“人生可以归结为一种简单的选择:不是忙着活,就是忙着死。” 多深刻,多简单,又多令人深省, 哪有那么多选择 哪有那么多时间去花费在无意义的事情上,要么忙着活,要么赶着去死
一:题目
二:思路
1.前提
注意这里的数组一定要是有序的,并不是任何数组均可用二分法查找target,他必须有序才可
2:左闭右闭(指的是区间)
(1):while(left<=right)中的 <=
这里的等于号 是当 left == right 的时候,这个区间[left,right]内我们还是可以找到target的
nums[1,4,7,9,11,13] 在这个数组中我们找target = 13
(2):区间的变化
我们每次在缩小的范围的时候采取的是[left,right],
当target < nums[mid]时候 right = mid - 1, 那么下次的搜索范围为[left,right]
当target > nums[mid]时候 left = mid +1,那么下次的搜索范围为[left,right]
3:左闭右开
(1):while(left < right)中的 <
在左闭右开的范围内,我们采用的是小于号,因为当left == right 的时候,在区间[left,right)是无范围的,nums[1,4,7,9,11,13] 在这个数组中我们找target = 1(在左闭右开的中 right = 5是不对的 应该为 6 (数组的大小))
在这个范围中,我们并在最后的区间[0,1)找到的taget,,也就是最终我们查找的最小范围必须是两个数,那么就不可能有left == right,因为此时是无范围的
(2):区间的变化
我们每次缩小范围的时候采用的是[left,right)
当target < nums[mid] 的时候 right = mid 那么下次的搜索空间[left,right)
当target > nums[mid] 的时候 left = mid +1 那么下次的搜索空间为[left,right)
三:上码
1:左闭右闭
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)/2;if(nums[mid] < target){left = mid + 1;}if(nums[mid] > target){right = mid - 1;}if(nums[mid] == target){return mid;}}return -1;}
};
2:左闭右开
class Solution {
public:int search(vector<int>& nums, int target) {int left = 0;int right = nums.size();//这里我们需要注意我们最小的区间范围需要有两个元素,那么当数组元素的个数为1时 [0,1),也是包含两个元素的while(left < right){int mid = (left + right)/2;if(nums[mid] < target){left = mid + 1;}if(nums[mid] > target){right = mid;}if(nums[mid] == target){return mid;}}return -1;}
};
四:总结
这是菜鸡杰的二刷,二分法看似简单,分析起来也容易理解,但是但是往往这种题值得推敲的细节 就比较重要,希望兄弟们注意,它的边界和区间变化 如有疑问 请留言 加油陌生人!!