=====二分查找=====
=====二分答案=====
技巧总结:“最多”--->思考答案是否具有二段性,使用二分答案的好处就在于“多一个条件”(多固定一个条件)。
Leetcode 2576. 求出最多标记下标
思考过程:
方法一:贪心+二分答案
class Solution {
public:
// 二分答案,多增加一个条件
int maxNumOfMarkedIndices(vector<int>& nums) {
int n = nums.size();
sort(nums.begin(), nums.end());
auto check = [&](int mid) ->bool{ // mid对下标
for(int j = 0; j < mid; j ++)
if(nums[j] * 2 > nums[n - mid + j]) return false;
return true;
};
int l = 0, r = n / 2;
while(l < r){
int mid = (l + r + 1) >> 1;
if(check(mid)) l = mid;
else r = mid - 1;
}
return l * 2;
}
};
方法二:贪心+双指针
class Solution {
public:
int maxNumOfMarkedIndices(vector<int>& nums) {
ranges::sort(nums);
int i = 0, n = nums.size();
for (int j = (n + 1) / 2; j < n; j++) {
if (nums[i] * 2 <= nums[j]) { // 找到一个匹配
i++;
}
}
return i * 2;
}
};
Leetcode 2398. 预算内的最多机器人数目
读题中,注意连续运行的含义是:下标是连续的才行。
方法一:RMQ+前缀和+二分答案
显然这个答案具有“二段性”,那么可以二分,外循环时间复杂度变成logn级别。
看了下数据范围,大概是要求nlogn及以内才能过掉。然后二分枚举的每一个长度为k的区间中,需要O(n)来枚举每一个区间,所以查询区间最大值max和区间的sum只能用O(1)的时间,所以结合静态数组的特性,只能使用RMQ和前缀和来完成查询。
class Solution { public: long long pre[50010] = {0}; // 前缀和数组 long long f[50010][17]; // ST表 int n; void init(vector<int>& w){ for(int j = 0; j < 17; j ++) for(int i = 0; i + (1 << j) - 1 < n; i ++) if(!j) f[i][j] = w[i]; else f[i][j] = max(f[i][j - 1], f[i + (1 << j)][j - 1]); } int query(int l, int r){ // 返回某个区间的最大值 int len = r - l + 1; int k = log(len) / log(2); // 自动下取整 return max(f[l][k], f[r - (1 << k) + 1][k]); } // 二分答案 int maximumRobots(vector<int>& chargeTimes, vector<int>& runningCosts, long long budget) { n = chargeTimes.size(); int l = 0, r = n; // 搜索的区间别搞错了, 最大是可以连续运行n个机器人的 init(chargeTimes); // 初始化st表 for(int i = 0; i < n; i ++) pre[i + 1] = pre[i] + runningCosts[i]; auto check = [&](int k) -> bool{ // 看这个k能不能行得通(得用O(n)的时间) for(int i = 0; i + k - 1 < n; i ++){ int l = i, r = i + k - 1; if ((query(l, r) + k * (pre[r + 1] - pre[l])) <= budget) return true; }return false; }; while (l < r){ int mid = (l + r + 1) >> 1; if(check(mid)) l = mid; else r = mid - 1; } return l; } };
方法二:单调队列/滑动窗口
见博客滑动窗口专题-CSDN博客https://blog.csdn.net/zjjaibc/article/details/140856804?spm=1001.2014.3001.5501