真正写对「二分查找」,从来不在于我们把区间写成了「左闭右开」还是「左闭右闭」,而是 在于我们能够根据题意:得到某种单调性,和可以逐步缩小搜索规模的条件,进而准确地设计可以使得搜索区间缩小的条件。
735. 行星碰撞(145)
代码实现(首刷自解)
class Solution {
public:
vector<int> asteroidCollision(vector<int>& asteroids) {
vector<int> ans;
int n = asteroids.size();
for (int asteroid : asteroids) {
if (ans.empty() || !(asteroid < 0 && ans.back() > 0)) {
ans.push_back(asteroid);
continue;
}
bool flag = true;
while (!ans.empty() && asteroid * ans.back() < 0) {
int tmp = ans.back();
if (abs(tmp) > abs(asteroid)) {
flag = false;
break; // 新的被碰坏
}
ans.pop_back();
if (abs(tmp) == abs(asteroid)) {
flag = false;
break; // 新旧一起坏
}
if (abs(tmp) < abs(asteroid)) continue; // 旧的被碰坏,继续
}
if (flag) ans.push_back(asteroid);
}
return ans;
}
};
1870. 准时到达的列车最小时速(146)
代码实现(首刷自解)
class Solution {
public:
int minSpeedOnTime(vector<int>& dist, double hour) {
int n = dist.size();
if (n - 1 >= hour) return -1;
int l = 1, r = 1e7;
while (l < r) {
int m = (l + r) / 2;
double count = 0;
for (int i = 0; i < n - 1; i++) {
count += dist[i] / m + (dist[i] % m != 0);
}
count += double(dist.back()) / m;
if (count <= hour) r = m;
else l = m + 1;
}
return l;
}
};
1898. 可移除字符的最大数目(147)
代码实现(首刷自解)
class Solution {
public:
int maximumRemovals(string s, string p, vector<int>& removable) {
int n = removable.size();
int l = 0, r = min(n, int(s.size() - p.size()));
string tmp;
while (l < r) {
int m = (l + r + 1) >> 1;
tmp = s;
for (int i = 0; i < m; i++) {
tmp[removable[i]] = ' ';
}
int i = 0;
bool flag = false;
for (char c : tmp) {
if (c == p[i]) i++;
if (i == p.size()) {
flag = true;
break;
}
}
if (flag) l = m;
else r = m - 1;
}
return l;
}
};