二分&三分算法
二分算法模板
边界要求:二分答案时,我们最终的答案是由mid进行判定,然后通过移动l或r来缩小范围。当我们的数据中所有的数据都无法使l进行移动,l指向一个未定值(-1)表示l没有用到。所以,我们二分模板中的l, r分别指向L - 1, R + 1。
while(l + 1 < r) { int mid = l + r >> 1; if(check(mid)) l = mid; else r = mid; }
三分算法最后的答案是min(f(l), f(l + 1), f(r)) 或者 min(f(l), f(r)) 我们不能使l或r处于未定态及不能有 L - 1, R + 1 这种越界下标存在。所以l = L, r = R即可。
三分算法模板1: 由二分算法变过来, 长得和二分模板像,当 l = m1的时候,范围缩减1/2 反之缩减1/4
l, r = 0, 99999
while l + 1 < r:
m1 = (l + r) // 2
m2 = (m1 + r) // 2
f1 = cost(m1, flag)
f2 = cost(m2, flag)
if f1 > f2:
l = m1
else:
r = m2
三分算法模板2: 字面意义上的三分,每次左侧右侧都是缩减1/3
def search(flag: int) -> int: l, r = 0, 99999 while l + 2 < r: m1 = (l * 2 + r) // 3 m2 = (l + r * 2) // 3 f1 = cost(m1, flag) f2 = cost(m2, flag) if f1 > f2: l = m1 else: r = m2

class Solution { public: int findRadius(vector<int>& houses, vector<int>& heaters) { int n = houses.size(), m = heaters.size(); sort(houses.begin(), houses.end()); sort(heaters.begin(), heaters.end()); auto check = [&](int rid) -> bool { for(int i = 0, j = 0; i < n; i ++ ) { while(j < m && houses[i] > heaters[j] + rid) j ++ ; if(j < m && heaters[j] - rid <= houses[i] && heaters[j] + rid >= houses[i]) continue; return false; } return true; }; int l = -1, r = 1e9; while(l + 1 < r) { int mid = l + r >> 1; if(check(mid)) r = mid; else l = mid; } return r; } };

class Solution { public: int hIndex(vector<int>& citations) { sort(citations.begin(), citations.end()); int n = citations.size(); int l = -1, r = n + 10; auto check = [&](int mid) -> bool { int cnt = citations.end() - lower_bound(citations.begin(), citations.end(), mid); return cnt >= mid; }; while(l + 1 < r) { int mid = l + r >> 1; if(check(mid)) l = mid; else r = mid; } return l; } };

class Solution { public: int minEatingSpeed(vector<int>& piles, int h) { int n = piles.size(); int l = 0, r = *max_element(piles.begin(), piles.end()) + 10; auto check = [&](int mid) -> bool { long t = 0; for(auto it: piles) { t += (it + mid - 1) / mid; } return t <= h; }; while(l + 1 < r) { int mid = l + r >> 1; if(check(mid)) r = mid; else l = mid; } return r; } };

浙公网安备 33010602011771号