记录日常学习与做题
2021-04-02 面试题17.21直方图的水量
难度不是很大 官方给出三种做法 动态规划/单调栈/双指针
第一眼看到这题想到的是双指针
思路:设置left指针指的是一个较大的值,设置为high 将right向右不断移动 直到移动到的数大于等于left指向的数接着把left指针向右移动 此时的水都是可以接到的,装到的量为high-height[left]如果移到数组最后都没有找到大于等于left指向的数 那么将此时的left设置为之后遍历到的最大值,再重复上述过程
class Solution {
public static int trap(int[] height) {
int left = 0;
int right = left + 1;
int res = 0;
while (right < height.length) {
while (right < height.length && height[right] < height[left])//设置left指针为最大值
{
right++;
}
if (right == height.length) {//若出现右指针的数找不到大于等于左指针的数
int max = 0;
for (int i = left + 1; i < height.length; i++) {
max = Math.max(height[i], max);
}
height[left] = max; //将左指针的数设置为之后的最大值再继续
right = left + 1;
} else {
int high = height[left];
do {
res += high - height[left];
left++;
} while (left != right);
right++;
}
}
return res;
}
}
官方给出了动态规划 也很好理解 从左边遍历一遍得到leftmax,再从右边遍历一遍得到rightmax,取交集
class Solution {
public int trap(int[] height) {
int n = height.length;
if (n == 0) {
return 0;
}
int[] leftMax = new int[n];
leftMax[0] = height[0];
for (int i = 1; i < n; ++i) {
leftMax[i] = Math.max(leftMax[i - 1], height[i]);
}
int[] rightMax = new int[n];
rightMax[n - 1] = height[n - 1];
for (int i = n - 2; i >= 0; --i) {
rightMax[i] = Math.max(rightMax[i + 1], height[i]);
}
int ans = 0;
for (int i = 0; i < n; ++i) {
ans += Math.min(leftMax[i], rightMax[i]) - height[i];
}
return ans;
}
}