题目描述
给定n个非负整数表示每个宽度为1的柱子的高度图就,计算按此排列的柱子,下雨之后能接多少雨水。
举例:
上图浅绿的表示柱子的高度,深蓝色的表示最多能接的雨水量。
输入:nums={3, 1, 0, 2, 1} 输出:3
解题思路:双指针。左右两个指针left和right同时扫描数组,用两个变量记录当前左右两边的最大值lmax和rmax,然后比较lmax和rmax,将小一边计算当前的接雨量,同时更新对应的运行指针。
代码
#include <iostream>
#include <vector>
int get_water_num(const std::vector<int>& nums) {
int n = nums.size();
int water_num = 0;
int lmax = 0;
int rmax = 0;
int left = 0;
int right = n - 1;
while (left <= right) {
lmax = std::max(nums[left], lmax);
rmax = std::max(nums[right], rmax);
if (lmax <= rmax) {
water_num += (lmax - nums[left]);
left++;
} else {
water_num += (rmax - nums[right]);
right--;
}
}
return water_num;
}
void print_result(const std::vector<int>& input, int output) {
// input
std::cout << "input:";
for (auto value : input) {
std::cout << value << " ";
}
std::cout << std::endl;
// output
std::cout << "output:" << output << std::endl;
}
int main()
{
// case1: nums={0,1,0,2,1,0,1,3,2,1,2,1} ==> 6
auto nums = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};
auto result = get_water_num(nums);
print_result(nums, result);
// case2: nums={4,2,0,3,2,5} ==> 9
nums = {4, 2, 0, 3, 2, 5};
result = get_water_num(nums);
print_result(nums, result);
// case3: nums = {3, 1, 0, 2, 1}
nums = {3, 1, 0, 2, 1};
result = get_water_num(nums);
print_result(nums, result);
return 0;
}
代码运行结果如下:
input:0 1 0 2 1 0 1 3 2 1 2 1
output:6
input:4 2 0 3 2 5
output:9
input:3 1 0 2 1
output:3