intlowerBound(vector<pair<int, int>>& arr, int target){ int l = 0, r = arr.size(); // r = size,不是 size-1 while (l < r) { int m = (l + r) / 2; if (arr[m].first < target) l = m + 1; else r = m; } return l; // 可能返回 size(全部小于 target) }
③ 取值时判断越界
当 p == 0 时,左侧为空,只能用 sufMinEnd[0]。当 p == m 时,右侧为空,只能用 landEnd + preMinDur[m-1]:
int p = lowerBound(waterPair, landEnd); if (p > 0) time = min(time, landEnd + preMinDur[p - 1]); // 左侧存在 if (p < m) time = min(time, suMinEnd[p]); // 右侧存在
完整代码(排序 + 二分 + 预处理方案)
classSolution { intlowerBound(vector<pair<int, int>>& arr, int target){ int l = 0, r = arr.size(); while (l < r) { int m = (l + r) / 2; if (arr[m].first < target) l = m + 1; else r = m; } return l; }
public: intearliestFinishTime(vector<int>& landStartTime, vector<int>& landDuration, vector<int>& waterStartTime, vector<int>& waterDuration){ int n = landStartTime.size(), m = waterStartTime.size();
// 构建 pair 并排序 vector<pair<int, int>> landPair(n), waterPair(m); for (int i = 0; i < n; i++) landPair[i] = {landStartTime[i], landDuration[i]}; for (int j = 0; j < m; j++) waterPair[j] = {waterStartTime[j], waterDuration[j]}; ranges::sort(landPair); ranges::sort(waterPair);
// 先陆地后水上 — 基于 waterPair 预处理 vector<int> preMinDur(m), sufMinEnd(m); int minDur = waterPair[0].second; for (int j = 0; j < m; j++) { minDur = min(minDur, waterPair[j].second); preMinDur[j] = minDur; } int minEnd = waterPair[m - 1].first + waterPair[m - 1].second; for (int j = m - 1; j >= 0; j--) { minEnd = min(minEnd, waterPair[j].first + waterPair[j].second); sufMinEnd[j] = minEnd; } int best = INT_MAX; for (auto& [s, d] : landPair) { int landEnd = s + d; int p = lowerBound(waterPair, landEnd); if (p > 0) best = min(best, landEnd + preMinDur[p - 1]); if (p < m) best = min(best, sufMinEnd[p]); } int landToWater = best;