【LeetCode力扣】42. 接雨水

这篇具有很好参考价值的文章主要介绍了【LeetCode力扣】42. 接雨水。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1、题目介绍

2、解题思路

2.1、暴力破解法

2.2、双指针法


【LeetCode力扣】42. 接雨水,LeetCode刷题,leetcode,算法,java,数据结构,动态规划,intellij-idea

 文章来源地址https://www.toymoban.com/news/detail-719376.html

【LeetCode力扣】42. 接雨水,LeetCode刷题,leetcode,算法,java,数据结构,动态规划,intellij-idea 

1、题目介绍

原题链接: 42. 接雨水 - 力扣(LeetCode)

【LeetCode力扣】42. 接雨水,LeetCode刷题,leetcode,算法,java,数据结构,动态规划,intellij-idea

 示例 1:

 【LeetCode力扣】42. 接雨水,LeetCode刷题,leetcode,算法,java,数据结构,动态规划,intellij-idea

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 

 示例 2:

输入:height = [4,2,0,3,2,5]
输出:9

 提示:

  • n == height.length
  • 1 <= n <= 2 * 104
  • 0 <= height[ i ] <= 105 

2、解题思路

【LeetCode力扣】42. 接雨水,LeetCode刷题,leetcode,算法,java,数据结构,动态规划,intellij-idea

2.1、暴力破解法

首先看到这题的第一反应就是,通过每层遍历去找出蓝色块(即水块)。

只要找到每一层的边界,再通过右边界right - 左边界left + 1即可得出该层(蓝色块与黑色块)的总和,再通过遍历去掉黑色块,就能够得出单层的水块,最终将每一层水块累加则得出结果。

图解说明: 

第一层:

        通过计算找出第一层的边界,可以发现第一层的边界规律是,只要左边界left从左往右找到第一个大于等于1的柱子,即是左边界;而右边界right从右往左找到第一个大于等于1的柱子,即为右边界。再通过right - left + 1(即11-1+1 = 11)得到第一层所有所有区域总和len,然后从left进行遍历数组到right ,只要当前值大于等于1,则len自减1。最后减完之后得出的len即为第一层水块数。

【LeetCode力扣】42. 接雨水,LeetCode刷题,leetcode,算法,java,数据结构,动态规划,intellij-idea

第二层:

        同理,只要左边界left从左往右找到第一个大于等于2的柱子,即是左边界;而右边界right从右往左找到第一个大于等于2的柱子,即为右边界。再通过right - left + 1(即8)得到第二层所有所有区域总和len,然后从left进行遍历数组到right ,只要当前值大于等于2,则len自减1。最后减完之后得出的len即为第二层水块数。

【LeetCode力扣】42. 接雨水,LeetCode刷题,leetcode,算法,java,数据结构,动态规划,intellij-idea

第三层 :

        当边界left < right 时,循环结束,此时第三层的left等于right,直接退出循环,不需要计算。

【LeetCode力扣】42. 接雨水,LeetCode刷题,leetcode,算法,java,数据结构,动态规划,intellij-idea

 代码实现:

其中:

heightMax方法用于计算整个数组的最大值,也就是最大层数,最大层数有多少,就需要遍历多少次。

layerNumber方法用于计算每一层的水块个数。

class Solution {
    public int trap(int[] height) {
        int left = 0;
        int right = height.length - 1;
        int sum = 0;
        int max = heightMax(height);   //计算出最大层数
        for(int i = 1; i <= max; i++) {  //几层就循环几次
            if(left < right) {
                while(height[left] < i) {   //找出左边界
                    left++;
                }
                while(height[right] < i) {  //找出右边界
                    right--;
                }
                int ret = layerNumber(height,left,right,i);  //计算该层的水块
                sum += ret;  //sum记录水块个数
            }
        }
        return sum;
    }

    public int heightMax(int[] arr) {
        int max = arr[0];
        for(int i = 1; i < arr.length; i++) {
            max = max > arr[i] ? max : arr[i];
        }
        return max;
    }

    signal是当前所在层数
    public int layerNumber(int[] arr, int left, int right, int signal) {   
        int len = right - left + 1;   //画图理解+1
        for(int i = left; i <= right; i++) {
            if(arr[i] >= signal) {
                len--;
            }
        }
        return len;
    }
}

 但是由于是暴力破解,每层都需要依次遍历,因此时间复杂度和空间复杂度非常高。

【LeetCode力扣】42. 接雨水,LeetCode刷题,leetcode,算法,java,数据结构,动态规划,intellij-idea

下面给大家讲解一个巧妙运用双指针动态规划下快速计算出结果的算法。

2.2、双指针法

leftMax用于记录当前左指针left经过的最大高度,同理rightMax用于记录当前左指针right经过的最大高度。

下标 i 处能否接水以及接到水的数量其实取决于左指针left到 i 时所经过的最大高度leftMax右指针right到 i 时所经过的最大高度rightMax它们之间的较小值。

例如:

下标5处,它能接到水的数量是leftMax和rightMax的最小值减去下标 i 的高度。

【LeetCode力扣】42. 接雨水,LeetCode刷题,leetcode,算法,java,数据结构,动态规划,intellij-idea

再例如:

下标9处,它能接到水的数量是leftMax和rightMax的最小值减去下标 i 的高度。

【LeetCode力扣】42. 接雨水,LeetCode刷题,leetcode,算法,java,数据结构,动态规划,intellij-idea

代码实现: 

class Solution {
    public int trap(int[] height) {
        int left = 0;
        int right = height.length - 1;
        int leftMax = 0;
        int rightMax = 0;
        int sum = 0;
        while(left < right) {
            leftMax = Math.max(leftMax,height[left]);  //每次循环前判断最大值
            rightMax = Math.max(rightMax,height[right]); //每次循环前判断最大值
            //谁小移动谁,并且移动前计算当前位置与最大高度的差值,差值即水量数。
            if(leftMax > rightMax) {     
                sum += rightMax - height[right];
                right--;
            }else{    //相等时移动哪一个都可以,这里移动left
                sum += leftMax - height[left];
                left++;
            }
        }
        return sum;
    }
}

复杂度分析:

时间复杂度:O(n),其中 n 是数组 height 的长度。两个指针的移动总次数不超过 n。

空间复杂度:O(1)。只需要使用常数的额外空间。

使用该方法能够大大降低时间复杂度。

【LeetCode力扣】42. 接雨水,LeetCode刷题,leetcode,算法,java,数据结构,动态规划,intellij-idea

更多【LeetCode刷题】推荐:

【LeetCode力扣】189 53 轮转数组 | 最大子数组和-CSDN博客https://blog.csdn.net/zzzzzhxxx/article/details/134095703?spm=1001.2014.3001.5502

【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表-CSDN博客https://blog.csdn.net/zzzzzhxxx/article/details/133958602?spm=1001.2014.3001.5502 

【LeetCode力扣】86. 分隔链表-CSDN博客https://blog.csdn.net/zzzzzhxxx/article/details/133942678?spm=1001.2014.3001.5502 

 【LeetCode力扣】42. 接雨水,LeetCode刷题,leetcode,算法,java,数据结构,动态规划,intellij-idea

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

 

到了这里,关于【LeetCode力扣】42. 接雨水的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【动态规划】LeetCode-42. 接雨水

    42. 接雨水。 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 示例 2: 提示: 算法分析 解题思路 dp 复杂性分析 时间复杂度:O(n) 空间复杂度:O(n)

    2024年01月20日
    浏览(42)
  • LeetCode42.接雨水(单调栈)

    给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 思路: 从题目中我们可以知道:只有凹陷的地方才可以存储雨水,那么高度一定是先减后增,所以当我们遍历到 增 这个位置时,前面减的地方(即凹陷的地方)一定会存储

    2024年02月21日
    浏览(35)
  • java数据结构与算法刷题-----LeetCode283. 移动零

    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完): https://blog.csdn.net/grd_java/article/details/123063846 解题思路 双指针,用right和left两个指针,将非0元素,全部按顺序换到数组前面。left指向左边非0元素应该插入的位置,right找到非

    2024年01月21日
    浏览(49)
  • java数据结构与算法刷题-----LeetCode566. 重塑矩阵

    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完): https://blog.csdn.net/grd_java/article/details/123063846 代码:时间复杂度O(r*c).除题目要求外,算法本身没有需要额外空间,空间复杂度O(1) 从0开始算,一个3列n行矩阵中,每行就有3个元

    2024年01月21日
    浏览(46)
  • java数据结构与算法刷题-----LeetCode287. 寻找重复数

    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完): https://blog.csdn.net/grd_java/article/details/123063846 解题思路 弗洛伊德判圈法,也就是快慢指针判圈法(龟兔赛跑算法),此算法分为两个步骤 判断是否有环,并得到快慢指针相遇

    2024年01月24日
    浏览(43)
  • java数据结构与算法刷题-----LeetCode766. 托普利茨矩阵

    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完): https://blog.csdn.net/grd_java/article/details/123063846 解题思路 这道题只要换一种理解方式,瞬间就会变的很简单。 题目描述是每个元素左上和右下对角线元素都相同。但是,我们发

    2024年01月25日
    浏览(48)
  • java数据结构与算法刷题-----LeetCode667. 优美的排列 II

    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完): https://blog.csdn.net/grd_java/article/details/123063846 解题思路 题目要求我们返回一个数组长度为n的数组,必须含有1~n的所有数,并且从左到右,相邻的元素依次相减,它们的差,必

    2024年01月25日
    浏览(52)
  • java数据结构与算法刷题-----LeetCode240. 搜索二维矩阵 II

    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完): https://blog.csdn.net/grd_java/article/details/123063846 解题思路 法一:把整个数组遍历一遍,时间复杂度O(m*n) 法二:每一行用二分搜索,那么时间复杂度就是O(m * l o g 2 n log_2{n} l o g

    2024年01月22日
    浏览(61)
  • LeetCode-42. 接雨水【栈 数组 双指针 动态规划 单调栈】

    给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。

    2024年02月04日
    浏览(42)
  • java数据结构与算法刷题-----LeetCode209. 长度最小的子数组

    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完): https://blog.csdn.net/grd_java/article/details/123063846 解题思路 代码:时间复杂度O(n).空间复杂度O(1)

    2024年01月21日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包