整数二分
模板
模板来自于AcWing:
int[] nums = new int[n];// 模板1:
// l = mid
// mid = l + r + 1 >> 1;
int l = 0, r = n - 1; // [0, n - 1]
while (l < r) {int mid = l + r + 1 >> 1;if (check(mid)) l = mid;else r = mid - 1;
}// 模板2:
// r = mid
// mid = l + r >> 1;
int l = 0, r = n - 1; // [0, n - 1]
while (l < r) {int mid = l + r >> 1;if (check(mid)) r = mid;else l = mid + 1;
}
题型
找到=target 的数/下标
两个模板都可以
int[] nums = new int[n];
int targetint l = 0, r = n - 1; // [0, n - 1]
while (l < r) {int mid = l + r + 1 >> 1;if (nums[mid] <= target) l = mid;else r = mid - 1;
}
return nums[l] == target;int l = 0, r = n - 1; // [0, n - 1]
while (l < r) {int mid = l + r >> 1;if (nums[mid] >= target) r = mid;else l = mid + 1;
}
return nums[r] == target;
找到最后一个<=target 的数/下标
因为是找到最后一个,所以当满足<=target 的时候,就更新 l,让 mid 不停的往右移动就能找到最后一个了。所以用模板 1。
int l = 0, r = n - 1; // [0, n - 1]
while (l < r) {int mid = l + r + 1 >> 1;if (nums[mid] <= target) l = mid;else r = mid - 1;
}
找到第一个>=target 的数/下标
因为是找到第一个,所以当满足>=target 的时候,就更新 r,让 mid 不停的往左移动就能找到第一个了。所以用模板 2。
int l = 0, r = n - 1; // [0, n - 1]
while (l < r) {int mid = l + r >> 1;if (nums[mid] >= target) r = mid;else l = mid + 1;
}
浮点数二分
while(r - l > eps) {double mid = (l + r) / 2;if(...) l = mid;else r = mid;
}