代码随想录算法训练营day59 | 503.下一个更大元素II,42. 接雨水

news/2024/11/15 2:04:49/

代码随想录算法训练营day59 | 503.下一个更大元素II,42. 接雨水

  • 503.下一个更大元素II
    • 解法一:单调栈(两次遍历解决环状问题)
  • 42. 接雨水
    • 解法一:单调栈(横向累计)
    • 解法二:暴力解法
    • 解法三:双指针优化
  • 总结


503.下一个更大元素II

教程视频:https://www.bilibili.com/video/BV15y4y1o7Dw
在这里插入图片描述

解法一:单调栈(两次遍历解决环状问题)

class Solution {public int[] nextGreaterElements(int[] nums) {int[] result = new int[nums.length];Arrays.fill(result, -1);Deque<Integer> stack = new LinkedList<>();stack.push(0);int n = nums.length;for(int i=1;i<2*n;i++){if(nums[i%n]<=nums[stack.peek()]){stack.push(i%n);}else{while(!stack.isEmpty() && nums[i%n]>nums[stack.peek()]){result[stack.peek()]=nums[i%n];stack.pop();}stack.push(i%n);}}return result;}
}

42. 接雨水

教程视频:https://www.bilibili.com/video/BV1uD4y1u75P
在这里插入图片描述

解法一:单调栈(横向累计)

找到左右第一个比当前元素高的值,选其中小的高督察乘以宽度得到当前雨水层的水。
在这里插入图片描述

class Solution {public int trap(int[] height) {Deque<Integer> stack = new LinkedList<>();stack.push(0);int result=0;for(int i=1;i<height.length;i++){if(height[i]<height[stack.peek()]){stack.push(i);}else if(height[i]==height[stack.peek()]){// 因为相等的相邻墙,左边一个是不可能存放雨水的,所以pop左边(前一个)index, push当前的indexstack.pop();stack.push(i);}else{while(!stack.isEmpty() && height[i]>height[stack.peek()]){int curIndex = stack.pop();if(!stack.isEmpty()){//左侧遍历过的元素,大于当前值的最近元素就在栈口第二个位置// System.out.println("right: "+i+", "+height[i]+", mid: "+curIndex+", "+height[curIndex]+", left: "+stack.peek()+", "+height[stack.peek()]);int h = Math.min(height[i], height[stack.peek()])-height[curIndex];int w = i-stack.peek()-1;result+=h*w;}}stack.push(i);}}return result;}
}

解法二:暴力解法

按照列来计算,比较容易理解。如果按照列来计算的话,宽度一定是1了,我们再把每一列的雨水的高度求出来就可以了。
在这里插入图片描述
可以看出每一列雨水的高度,取决该列 左侧最高的柱子右侧最高的柱子 中最矮的那个柱子的高度

首先从头遍历所有的列,并且要注意第一个柱子和最后一个柱子不接雨水。在for循环中求左右两边最高柱子。最后,计算该列的雨水高度。

因为每次遍历列的时候,还要向两边寻找最高的列,所以时间复杂度为O(n^2),空间复杂度为O(1)。
力扣上暴力解法超时了。

class Solution {public int trap(int[] height) {int result=0;for(int i=0;i<height.length;i++){if(i==0 || i==height.length-1){continue;}int leftMax = height[i];int rightMax = height[i];for(int j=i-1;j>=0;j--){if(height[j] > leftMax) leftMax = height[j];}for(int j=i+1;j<height.length;j++){if(height[j]>rightMax) rightMax =height[j];}if(leftMax!=0 && rightMax!=0){result+=Math.min(leftMax, rightMax)-height[i];}}return result;}
}

解法三:双指针优化

为了得到两边的最高高度,使用了双指针来遍历,每到一个柱子都向两边遍历一遍,这其实是有重复计算的。我们把每一个位置的左边最高高度记录在一个数组上(maxLeft),右边最高高度记录在一个数组上(maxRight),这样就避免了重复计算。

当前位置,左边的最高高度是前一个位置的左边最高高度和本高度的最大值。
从左向右遍历:maxLeft[i] = max(height[i], maxLeft[i - 1]);
从右向左遍历:maxRight[i] = max(height[i], maxRight[i + 1]);

class Solution {public int trap(int[] height) {int length = height.length;if (length <= 2) return 0;//记录左右诸子的最大高度,避免重复遍历int[] maxLeft = new int[length];int[] maxRight = new int[length];// 记录每个柱子左边柱子最大高度maxLeft[0] = height[0];for (int i = 1; i< length; i++) maxLeft[i] = Math.max(height[i], maxLeft[i-1]);// 记录每个柱子右边柱子最大高度maxRight[length - 1] = height[length - 1];for(int i = length - 2; i >= 0; i--) maxRight[i] = Math.max(height[i], maxRight[i+1]);// 求和int result = 0;for (int i = 0; i < length; i++) {int count = Math.min(maxLeft[i], maxRight[i]) - height[i];if (count > 0) result += count;}return result;}
}

总结

1、环形问题可以用遍历两遍+索引求余的方法处理。
2、用单调栈可以一次遍历就找出左右第一个比当前元素高/矮的值。
3、单调栈相关题目一定要确定,栈口元素和当前遍历的元素三种大小关系(>,<,=)下的处理方案。


http://www.ppmy.cn/news/166460.html

相关文章

给华为S5700交换机配下链路聚合

学习目标 掌握接口速率的配置方法 掌握使用手动模式配置链路聚合的方法 掌握使用静态LACP模式配置链路聚合的方法 掌握在静态LACP模式下配置接口优先级的方法 拓扑图 图4.1 以太网链路聚合拓扑图 场景 您是公司的网络管理员。现在公司购买了两台华为的S5700系列的交换机…

华为交换机vlan配置举例_华为S5700系列配置实例

原标题:华为S5700系列配置实例 华为S5700系列配置 一、#telnet远程登录 步骤一:创建VLAN,并配置交换机VLAN的管理IP # 创建vlan system-view [Quidway] vlan xxx (vlanID) [Quidway-vlanID] quit # 配置管理 IP [Quidway] interface vlan ID [Quidway-VlanifID] ip address …

华为交换基本配置命令--S5700为例

华为S5700交换配置命令 Sava 配置完交换机后保存当前配置命令 System-view 进入系统视图命令 Display current-configuration 查询当前配置 Console口进入用户界面 User-interface console 0 进入第0个console用户界面 Authentication-mode passwd 配置从console口登入交换机模…

华为交换机linux版本号,华为交换机S5700升级实例

华为交换机S5700升级实例 近期我写了一篇文章,是在测试vSphere虚拟交换机中的"专用VLAN",此功能需要上层交换机的支持。专用VLAN,思科称为PVLAN,华为称为MUX VLAN。 文章详见 http://wangchunhai.blog.51cto.com/225186/1857192 我的环境中都是华为的交换机。先在…

给这台华为S5700交换机配一下链路聚合

掌握接口速率的配置方法 掌握使用手动模式配置链路聚合的方法 掌握使用静态LACP模式配置链路聚合的方法 掌握在静态LACP模式下配置接口优先级的方法 图4.1 以太网链路聚合拓扑图 您是公司的网络管理员。现在公司购买了两台华为的S5700系列的交换机&#xff0c;为了提高交…

华为s5700交换机使用配置

文章目录 说明结论同网段直接接入不同网段直接接入 说明 这次要做的是不做任何配置&#xff0c;将设备接到交换机上&#xff0c;测试会发生什么交换机默认在配置模式下输入命令(即登录设备后执行system-view命令) 结论 如果华为s5700交换机没做任何配置 No说明1将同网段设备…

华为交换机初始化_华为S5700交换机初始化配置举例

基础设置: 配置登陆IP地址 system-view //进入系统配置模式 [Quidway]interface Vlanif 1 //进入三层 vlanif 接口 [Quidway-Vlanif1]ip address 19…

华为eNsp S5700组网配置

文章目录 网络拓扑网络规划网络配置Core交换机Telnet配置ACC1 配置CORE配置VLAN互通CORE ACC1配置DHCP服务器关闭接口的生成树协议配置连接终端设备的交换机接口为边缘端口Core配置静态路由出口路由器 配置ACC1 配置DHCP Snooping和IPSG保存配置 网络拓扑 在小型园区中&#xf…