二分
只要证明具有二段性,二分法就有用武之地。
基本的两个思路
- 在循环体里找元素:
好理解 但是不好用 因为分成了三部分,不适合高级情况 - 在循环体里排除一定不存在的区间(先排除):
好用 分成了两部分并且是没有交集的 要考虑的更少
l = r 的时候就退出,此时只剩下一个元素,直接在外面判断
剩两个元素的时候,要向上取整,不然就死循环了
public class Solution {
public int search(int[] nums, int target) {
int len = nums.length;
int left = 0;
int right = len - 1;
while (left < right) {
int mid = left + (right - left) / 2;
//这里就属于先排除 不包括等号
if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid;
}
}
if (nums[left] == target) {
return left;
}
return -1;
}
}
为什么需要向上取整?
主要是因为l = m
,对于l和r相连的情况,这就是没变化(r = m就不会有这个问题)
只需要(right - left + 1) / 2
就好了
最左和最右
旋转
最小
: 比最后一个。找规律的时候不要懵逼了,就找m和最小值的关系,来取舍左还是右
重最小
:逻辑类似,需要考虑等于,r-=1
搜索
:用og,找到了就返回。比较的时候有三种情况,肯定要从最小的开始,不然乱套
重搜索
:本质在于二段性,先恢复二段性。代码和上面一样。
山峰
二分答案-另一个次元
刷题
- 121 不会很难