二分法精髓
- 函数的单调性 + 计算内容重复
猜+判定
- 猜答案,根据判定结果修正答案
解题流程
- 判定答案的范围,L、R 再来猜答案
- 找到单调关系
- 定义guess函数,来判断猜的答案与
-
注意点
mid = (L+R)/2, 在进行加法运算时会超过int范围
- 区间问题:
- 左闭右开[L, R):mid = (L+R)/2,区间划分的时候去除掉mid,L = mid+1; R = mid;
- 左闭右闭[L, R]:mid = (L+R)/2,区间划分的时候去除掉mid,L = mid+1; R = mid-1;
- 循环结束条件:左闭右开[L, R) L<R; 左闭右闭[L, R] L<= R
- 无论那种区间,要对ans进行判断,考虑target 不在 数组中的情况
分割区间
[st, mid-1] mid [mid+1, ed] 运行条件st<=ed
[st, mid) mid [mid+1, ed) 运行条件st<ed
避免整形int溢出
- 转long
- 改 int mid = (L + R) / 2 —-> int mid = L + (R-L)/2 —-> int mid = (L + R)/2 >>> 1
LeetCode-69
实现 int sqrt(int x) 函数。
思路:
左闭右开[L, R)**
class Solution {public boolean guess(long x, long y) {return (long)x * x <= y;}// 二分法public int mySqrt(int y) {// 初始化区间long L = 0, R = (long)y + 1;// 保留整数,所以一般来说x*x <= ylong ans = 0;while(L < R) {long mid = (L + R) / 2;if(guess(mid, y)) {ans = mid;L = mid + 1;} else {R = mid;}}return (int) ans;}}
左闭右闭[L, R]
class Solution {
public boolean guess(long x, long y) {
return (long)x * x <= y;
}
// 二分法
public int mySqrt(int y) {
// 初始化区间
long L = 0, R = (long)y;
// 保留整数,所以一般来说x*x <= y
long ans = 0;
while(L <= R) {
long mid = (L + R) / 2;
if(guess(mid, y)) {
ans = mid;
L = mid + 1;
} else {
R = mid-1;
}
}
return (int) ans;
}
}
LeetCode 4 寻找两个正序数组的中位数
- 转化为求解第k大的数
- 当总长度len为奇数时,求解k=len/2+1大的数
- 当总长度len为偶数时,求解k=len/2+1大的数 和 k = len/2大数的 平均值
- 举例
nums1 = [1, 3]
nums2 = [2]
len = 3,要找第k = 1 + 1大的数
- nums1 pivot1 = 1, nums2 pivot2 = 2, 选择pivot1,计数0-0+1—> 再nums1= [3] nums2 = [2] 中找第0大的
- 此时 k = 1, 选择nums1 nums2中位数较小的一个
