当前位置: 首页 > article >正文

LeetCode -Hot100 - 42. 接雨水

前言

本专栏主要通过“LeetCode 热题100”,来捡起自己本科阶段的算法知识与技巧。语言主要使用c++/java。如果同样正在练习LeetCode 热题100的朋友欢迎关注或订阅本专栏。有疑问欢迎留言交流~

题目描述

题目链接
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
在这里插入图片描述
提示:
n == height.length
1 <= n <= 2 * 10^4
0 <= height[i] <= 10^5

思路

要求总的雨水量,我们可以把问题拆解。即求单个高度可以蓄多少水,之和即为总水量。那么如何寻找单个高度呢,即左右分别遍历查找,找到比它高的柱子即可。第一版代码如下:

class Solution {
public:
    int findCurHeight(int curi,vector<int>& height){
        int curheight = height[curi];
        int curleftMax = 0;
        int currightMax = 0;
        // 找左边大于i的最大值
        for (int i=0;i<curi;i++){
            curleftMax = max(curleftMax,height[i]);
        }
        // 找右边
        for (int i=curi+1; i<height.size();i++){
            currightMax = max(currightMax,height[i]);
        }
        //cout<<curleftMax<<" "<<currightMax<<endl;
        return max(0,min(curleftMax, currightMax) - curheight);
    }
    int trap(vector<int>& height) {
        int size = height.size();
        int cursum = 0;
        for (int i=1;i<size-1;i++){
            cursum += findCurHeight(i, height);
            //cout<<findCurHeight(i, height);
        }
        return cursum;
    }
};

提交后,发现时间超时,得优化。
优化思路其实也很简单,在计算每个位置的水量时,每次都需要遍历一次左边和右边的元素,导致时间复杂度是 O(n^2),这会在较大的输入下超时。可以通过预处理左右最大值数组来优化,从而避免重复计算(动态规划)。
具体来说,可以使用两个数组来存储每个位置的左侧最大值和右侧最大值。这样,每个位置的水量计算可以在常数时间内完成。新改版的代码如下:

class Solution {
public:
    int trap(vector<int>& height) {
        int size = height.size();
        if (size <= 2) return 0; // 如果只有2个或更少的柱子,无法形成任何水

        vector<int> leftMax(size, 0);
        vector<int> rightMax(size, 0);

        // 填充 leftMax 数组
        leftMax[0] = height[0];
        for (int i = 1; i < size; ++i) {
            leftMax[i] = max(leftMax[i - 1], height[i]);
        }

        // 填充 rightMax 数组
        rightMax[size - 1] = height[size - 1];
        for (int i = size - 2; i >= 0; --i) {
            rightMax[i] = max(rightMax[i + 1], height[i]);
        }

        // 计算总的积水量
        int totalWater = 0;
        for (int i = 1; i < size - 1; ++i) {
            // 计算当前位置能够容纳的水量
            int water = min(leftMax[i], rightMax[i]) - height[i];
            if (water > 0) {
                totalWater += water;
            }
        }

        return totalWater;
    }
};

提交,通过~


http://www.kler.cn/a/461808.html

相关文章:

  • Niushop商城商业插件_cps联盟_包装转换_视频购物_同城配送_上门预约等插件的安装方法
  • Swift Combine 学习(五):Backpressure和 Scheduler
  • 给vscode的新项目选择虚拟环境
  • PostgreSQL对称between比较运算
  • 数字货币支付系统开发搭建:构建未来的区块链支付生态
  • 数字孪生:物联+数据打造洞察世界新视角
  • HTML5 评分星级组件
  • 【Pytorch实用教程】循环神经网络中使用dropout需要注意的问题
  • [江科大STM32] 第五集快速建立STM32工程模板——笔记
  • Spring-kafka快速Demo示例
  • css实现图片填充文字
  • MySQL数据库——多版本并发控制MVCC
  • Linux基础指令(下)
  • Oracle 的网络配置文件详解
  • 基于通用优化软件GAMS的数学建模和优化分析实践技术应用
  • 2 秒杀系统架构
  • Jenkins管理多版本python环境
  • 云效流水线使用Node构建部署前端web项目
  • 深入浅出:AWT事件监听器及其应用
  • git仓库上传
  • Spring Bean required a single bean, but 2 were found,发现多个 Bean
  • 深入浅出:事件监听中的适配器模式
  • 微信小程序调用 WebAssembly 烹饪指南
  • 25年开篇之作---动态规划系列<七> 01背包问题
  • Python机器学习笔记(十六、数据表示与特征工程-分类变量)
  • Linux隐藏登录和清除历史命令以及其他相关安全操作示例