面试热题(接雨水问题)

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

我们看到题的第一步,永远是对入参进行判断

java 复制代码
    public int trap(int[] height) {
        if (height == null) {
            return 0;
        }
          ...
    }

但是我们想想看,接雨水是不是和往桶里倒水的问题很像,倒入水的体积往往是由桶两边较低的那个高度决定的,这个问题亦是如此

由我们分析可知当数组的长度小于3的时候,是不可能接到雨水的,所以我们在判断入参条件的时候就可以这样写

java 复制代码
  public int trap(int[] height) {
        if (height == null || height.length < 3) {
            return 0;
        }
         ...
    }

刚才我们已经分析过了,一个位置的存储量只和最短的那一边有关系,边越长,我们固定位置上的存储量就越多,所以我们可以遍历每个位置,分别计算出各个位置上的存储量,再最后求和就完美的解决了本题

java 复制代码
        int count = 0;
        for (int i = 1; i < height.length; i++) {
            //找左边的最高值
            int lMax = 0;
            for (int j = 0; j < i; j++) {
                lMax = Math.max(lMax, height[j]);
            }
            //找到右边的最高值
            int rMax = 0;
            for (int j = i + 1; j < height.length; j++) {
                rMax = Math.max(rMax, height[j]);
            }
           }

好了,这样我们相对位置上的两边最高的边已经求出来了,只不过现在还存一个问题,如果,当前位置的高度如果大于较小的那边高度的话,是否还可有存储水量呢?

所以当前位置的高度如果大于两边最长的相对较小的边的高度,则不能进行存储水量,所以我们再对我们的代码进行完善

java 复制代码
  int count = 0;
        for (int i = 1; i < height.length; i++) {
            //找左边的最高值
            int lMax = 0;
            for (int j = 0; j < i; j++) {
                lMax = Math.max(lMax, height[j]);
            }
            //找到右边的最高值
            int rMax = 0;
            for (int j = i + 1; j < height.length; j++) {
                rMax = Math.max(rMax, height[j]);
            }
            if (Math.min(lMax, rMax) - height[i] > 0) {
                count += Math.min(lMax, rMax) - height[i];
            }
        }

这就完成了我们所谓hard题的接雨水问题了,这个题面试中还是经常问的,希望大家透析原理,面试无压力,下面给大家奉上整个代码,供大家参考借鉴

java 复制代码
    public int trap(int[] height) {
        if (height == null || height.length < 3) {
            return 0;
        }
        int count = 0;
        for (int i = 1; i < height.length; i++) {
            //找左边的最高值
            int lMax = 0;
            for (int j = 0; j < i; j++) {
                lMax = Math.max(lMax, height[j]);
            }
            //找到右边的最高值
            int rMax = 0;
            for (int j = i + 1; j < height.length; j++) {
                rMax = Math.max(rMax, height[j]);
            }
            if (Math.min(lMax, rMax) - height[i] > 0) {
                count += Math.min(lMax, rMax) - height[i];
            }
        }
        return count;
    }
相关推荐
2301_780789666 小时前
跨平台适配!SDK 游戏盾兼容全终端游戏场景
java·网络·ddos
学长毕设7 小时前
基于springboot的食品仓库管理系统
java·spring boot·后端
步行cgn8 小时前
FormHttpMessageConverter 详解:Spring MVC 中表单数据的读写转换器
java·spring·mvc
龙亘川8 小时前
构建城市公共安全数字底座:亘川智城智慧安防系统全维度解读
java·大数据·开发语言·人工智能·信息可视化
金銀銅鐵8 小时前
[Java] 用 CLI 展示 EnumMap 增删键值对时的内部变化
java·源码·ai编程
秋天的怀念_David8 小时前
第二十二夜 · 数字迷雾
java·程序人生·算法
Raas1009 小时前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
Pniubi9 小时前
力扣283移动零(双指针法)
算法·leetcode·职场和发展
niucloud-admin9 小时前
NIUCLOUD PHP SAAS上门家政使用文档:城市管理
java·前端·php
霸道流氓气质10 小时前
智能客服组件:分层意图识别、RAG Advisor 与人工转接状态机的 Vue3 + Spring AI 生产级实战
java·人工智能·spring