int left = 0, right = chargeTimes.size()+1; while (left + 1 < right) { int mid = (left + right) / 2; if (check(mid)) left = mid; else right = mid; } return left;
这个时候 left 就是答案。
这里的check函数的作用是,检测k个连续的机器人是否合法,合法的标准是 max(chargeTimes) + k * sum(runningCosts)。转换一下,其实可以翻译成,在一个数组中,取n个长度为k的滑动窗口,判断这n个窗口中,是否存在一个窗口满足条件。
classSolution { public: deque<int> q; voidpush(int val){ while (!q.empty() && q.back() < val) q.pop_back(); q.push_back(val); } voidpop(int val){ if (!q.empty() && q.front() == val) q.pop_front(); } intmaximumRobots(vector<int>& chargeTimes, vector<int>& runningCosts, longlong budget){ function<bool(int)>check = [&](int k) { q.clear(); // 每次判断前 一定要进行初始化 否则会导致上一次的最大值残留 // 求取每个窗口的最大值 int l = 0, n = chargeTimes.size(); longlong sum = 0; for (int r = 0; r < n; ++r) { int len = r - l + 1; this->push(chargeTimes[r]); sum += runningCosts[r]; if (l <= n - k && len == k) { if ((q.front()+k*sum)<= budget) returntrue; this->pop(chargeTimes[l]); sum -= runningCosts[l++]; } } returnfalse; }; int left = 0, right = chargeTimes.size()+1; while (left + 1 < right) { int mid = (left + right) / 2; if (check(mid)) left = mid; else right = mid; } return left; } };
intlower_bound(vector<int>& nums, int target){ int l = 0, r = nums.size()-1; while (l <= r) { int mid = l + (r - l) / 2; if (target > nums[mid]) l = mid + 1; else r = mid - 1; } return l; }