目录
前言
本篇文章将介绍二分法的思路及例题
一、二分模板
废话少说,献上模板
模板1(闭区间)
//一
int search(int* nums, int numsSize, int target) {
int left = 0;int right = numsSize - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
//条件判断
if (nums[mid] == target) { return mid; }
else if (nums[mid] < target) { left = mid + 1; }
else { right = mid - 1; }
}
return -1;//找不到返回-1
}
//------------------------------------------
//二
int search(int* nums, int numsSize, int target) {
int left = 0;int right = numsSize - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
//条件判断
if (nums[mid] < target) { left = mid + 1; }
else { right = mid - 1; }
}
if (left<numsSize&&nums[left] == target) { return left; }
return -1;
}
模板2(左闭右开)
int search(int* nums, int numsSize, int target)
{int left = 0, right = numsSize-1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) { left = mid + 1; }
else { right = mid; }
}
if (left < numsSize && nums[left] == target) { return left; }
return -1;
}
模板3(开区间)
int search(int* nums, int numsSize, int target)
{
int left = 0, right = numsSize - 1;
while (left + 1 < right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid;
}
else {
right = mid;
}
}
if (right >=0 && nums[right] == target) { return right; }
return -1;
}
二,二分思想
1,引入
用来引入中心思想及用图理解
在解释各个模板之前,本人想法来自灵神及其评论区的讨论(视频链接在下方)https://www.bilibili.com/video/BV1AP41137w7/?vd_source=430c819dcfec0ed4686f19278a5b1e20中心思想:区间内的性质不重要,记住区间外的性质
模板1:闭区间,本人更习惯使用第二种(模板1),就用第二种为例讲(讲法是默认递增数组,从while条件入手,逐步推出while内left和right的更新条件)
模板1,while的结束条件是right在left右边,若我们认为最后是left在 target 的位置,那么有下图的关系
再解释上图中覆盖区域的意思:right一开始在数组最右边,移动方向自然只能向左移,那么导致right每次移动的条件就同样对覆盖区域有用
(举例:
if(nums[right]>1){right--;}
那么right走过的地方都满足nums[right]>1
这就是上面指向思想的本质:关注区间之外
)
2,具体分析
使用 “引入” 来分析并得出left和right的更新条件
回到本来的问题,target正好在两个区域交界,再结合二分的思想中mid(减半再分析)
如果mid对应的值大于target,那就更新right---------问题是怎么更新:
mid已经大了,那么就不要,让right=mid-1;
同理:mid<target-------left=mid+1;
mid==target--------return mid;
按上面的想法似乎可行,但这不是我一开始想要的模板1的第二种,
再结合上文的中心思想,
让if(left>mid),left=mid-1;
if(right<=mid),mid=right-1;
结合上面的图和中心思想:left左边是小于mid,right右边是大于等于mid
3,总结
模板1的染色法分析
再用该思路分析其他模板
模板2:从while的终止条件得出最后left=right;若left左边都小于target,我们要得到答案,就要right的右边及本身要大于等于target
从上面两个模板的不同,可以分析出:
由于while的终止条件不同,对left及right的更新条件也会不同,要根据终止条件及区间外重要的思想去构造更新条件
模板3也同理
所以最后return right
结语
“自己试试看吧”