[Algo] 双指针
1. 接雨水
// 1. 接雨水
// https://leetcode.cn/problems/trapping-rain-water/
int trap1(vector<int>& height) {
vector<int> arr_l, arr_r;
arr_l.resize(height.size());
arr_r.resize(height.size());
int lmax = INT32_MIN, rmax = INT32_MIN;
for (int i = 0; i < height.size(); i++)
{
if (height[i] > lmax) lmax = height[i];
arr_l[i] = lmax;
}
for (int i = height.size() - 1; i >= 0; i--)
{
if (height[i] > rmax) rmax = height[i];
arr_r[i] = rmax;
}
int ans = 0;
for (int i = 1; i < height.size() - 1; i++)
{
ans += max(min(arr_l[i - 1], arr_r[i + 1]) - height[i], 0);
}
return ans;
}
int trap2(vector<int>& height) {
int len = height.size();
int l = 1, r = len - 2, lmax = height[0], rmax = height[len - 1];
int ans = 0;
while (l <= r)
{
if (lmax <= rmax)
{
ans += max(lmax - height[l], 0);
lmax = max(lmax, height[l++]);
}
else
{
ans += max(rmax - height[r], 0);
rmax = max(rmax, height[r--]);
}
}
return ans;
}
2. 救生艇
// 2. 救生艇
// https://leetcode.cn/problems/boats-to-save-people/
int numRescueBoats(vector<int>& people, int limit) {
int ans = 0, l = 0, r = people.size() - 1, sum;
sort(people.begin(), people.end());
while (l <= r)
{
sum = l == r ? people[l] : people[l] + people[r];
if (sum > limit) { r--; ans++; }
else { l++; r--; ans++; }
}
return ans;
}
3. 供暖器
bool best(vector<int>& houses, vector<int>& heaters, int i, int j);
// 3. 供暖器
// https://leetcode.cn/problems/heaters/description/
int findRadius(vector<int>& houses, vector<int>& heaters) {
sort(houses.begin(), houses.end());
sort(heaters.begin(), heaters.end());
int m = houses.size(), n = heaters.size();
int ans = 0;
for (int i = 0, j = 0; i < m; i++)
{
while (!best(houses, heaters, i, j)) j++;
ans = max(ans, abs(houses[i] - heaters[j]));
}
return ans;
}
bool best(vector<int>& houses, vector<int>& heaters, int i, int j)
{
return (j == heaters.size() - 1) || (abs(houses[i] - heaters[j]) < abs(houses[i] - heaters[j + 1]));
}
4. 缺失的第一个正数
// 4. 缺失的第一个正数
// https://leetcode.cn/problems/first-missing-positive/
int firstMissingPositive(vector<int>& nums) {
int l = 0, r = nums.size();
// r 最好状态下,1...r能收集全,[r,...]为垃圾区
while (l < r)
{
if (nums[l] == l + 1) l++;
else if (nums[l] <= l || nums[l] > r || nums[nums[l] - 1] == nums[l]) swap(nums[l], nums[--r]);
// 移入垃圾区
else swap(nums[nums[l] - 1], nums[l]);
// 交换到该放的位置
}
return l + 1;
}