C++ leetcode接雨水
双指针算法“接雨水”
链接:https://leetcode-cn.com/problems/trapping-rain-water/
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
输入: [0,1,0,2,1,0,1,3,2,1,2,1] 输出: 6
class Solution { public: int trap(vector<int>& height) { int left = 0; int right = height.size() - 1; int left_bar_max = 0; int right_bar_max = 0; int ans = 0; //左指针、右指针重合跳出循环返回答案 while(left < right) { //左边高度小于右边高度,便从左到右遍历 if(height[left] < height[right]) { //左指针高度大于左边最大高度,将左边最大高度更新成左指针指向的高度 if(height[left] > left_bar_max) { left_bar_max = height[left]; } else { ans += left_bar_max - height[left]; } left++; } else { if(height[right] > right_bar_max) { right_bar_max = height[right]; } else { ans += right_bar_max - height[right]; } right--; } } return ans; } };
双指针解题思路:
left :从左到右的数组下标
right:从右到左的数组下标
left_bar_max:左边的最大值
right_bar_max:右边的最大值
当right_bar_max>left_bar_max,积水高度将由 left_bar_max 决定,类似地 left_bar_max>right_bar_max 积水的高度将由 right_bar_max 决定。
所以我们可以认为如果一端有更高的条形块(例如右端),积水的高度依赖于当前方向的高度(从左到右)。当我们发现另一侧(右侧)的条形块高度不是最高的,我们则开始从相反的方向遍历(从右到左)。
我们必须在遍历时维护left_bar_max 和right_bar_max,但是我们现在可以使用两个指针交替进行,实现 1 次遍历即可完成
right_bar_max
left_bar_max __ __ | | | |__ __?????????????????????? | | __| |__| __| |__ left right