[Java][Leetcode hard] 42. 接雨水

没做出来,看的官解。

1. 动态规划的思想

当位于i处,i处能接水的体积=左侧最高点和右侧最高点的最小值(水桶原理)-自身的高度

java 复制代码
class Solution {
    public int trap(int[] height) {
        int sum = 0;
        
        int n = height.length;
        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]);
        }
        for(int i=0;i<n;i++){
            sum += Math.min(rightMax[i], leftMax[i]) - height[i];
        }
        return sum;
    }
}

2. 采用单调栈计算

只要有凹槽就可以储水,首先将元素放入单调栈中,然后循环数组与栈顶对比。

此时:如果该元素(相当于右侧)大于栈顶的元素(相当于底部)再加上栈顶的下一个元素(相当于左侧,单调栈,栈顶元素一定小于第二个元素)就形成了凹槽。

java 复制代码
class Solution {
    public int trap(int[] height) {
        int n = height.length;
        int res = 0;
        Deque<Integer> stack = new ArrayDeque<>();
        for(int i = 0;i<n;i++){
            
            int right = i;
            while( !stack.isEmpty() && height[right] > height[stack.peek()]){
                int bottom  = stack.pop();

                if(stack.isEmpty()){
                    // 左侧无元素,无法形成凹槽
                    break;        
                }
                int left = stack.peek();
                int w = right - left - 1;
                int h = Math.min(height[right], height[left]) - height[bottom];

                res += w*h;

            }
            stack.push(i);
 
        }
        
        return res;
    }
}

3. 采用双指针

按照动态规划的思路,只需要维护leftMax,rightMax两个变量就可以将空间降至O(1)

java 复制代码
class Solution {
    public int trap(int[] height) {
        int res = 0;
        int left = 0,right = height.length - 1;
        int leftMax = 0,rightMax = 0;
        while(left < right){
            leftMax = Math.max(leftMax, height[left]);
            rightMax = Math.max(rightMax, height[right]);

            if(leftMax < rightMax){
            //  根据水桶原理,leftMax比rightMaxx小,此时,无论右边多大,水超过leftMax就会溢出。
                res += leftMax - height[left++]; 
            }else{
                 res += rightMax - height[right--]; 
            }
        }
        return res;
    }
}
相关推荐
一木 之林3 分钟前
插件、MCP、Skill 的区别?
java·c++·人工智能
可乐鸡翅yeah_7 分钟前
hls.js 播放质量埋点实战,采集卡顿、起播、错误指标定位线上用户问题
开发语言·前端·javascript·ecmascript·音视频·m3u8·音视频在线播放
小刘在重生~11 分钟前
面试重点:final、finalize、finally 三者区别
java
szarron24 分钟前
RF Demo Kit|NanoVNA 射频演示测试板完整上手教程,滤波器、衰减器、SOLT 校准学习板
开发语言·人工智能·学习·php·射频工程·频谱仪
边境悍匪35 分钟前
蜗牛学苑 Java 智能体学习 Day39|SpringAI 会话存储、Function‑Call 工具调用、MCP 思维导图复盘
java·开发语言·spring boot·学习·阿里云
万物智能信息科技1 小时前
RK3568 的多路显示移植—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
linux·开发语言·华为·开源·harmonyos
蓝悦无人机1 小时前
Qt Design Studio(QDS)4.8.2项目文件结构详解
开发语言·qt·qt creator·qds·项目文件结构·qtc
letisgo51 小时前
JAVA 高级进阶02篇《并发编程三板斧:JMM、CAS与AQS的源码级拆解》
java·面试·并发编程·aqs·jmm
胡写代码1 小时前
若依 + MyBatis-Plus,分页为什么悄悄失效了?
java·后端
yxlalm1 小时前
4.java秒杀项目第四课-后端商品后台接口
java·开发语言