【刷题笔记】接雨水||暴力通过||符合思维方式

接雨水

文章目录

  • 接雨水
    • 1 题目描述
    • 2 分析
      • 2.1 左到右
      • 2.2 右到左
      • 2.3 计算面积
    • 3 代码
      • 3.1 Java
      • 3.2 Python
    • 附录1

1 题目描述

https://leetcode.cn/problems/trapping-rain-water/

面试的时候关键不是你的手法多么精妙,首先要做出来。

在这里插入图片描述

给定 n 个非负整数表示每个宽度为 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 个单位的雨水(蓝色部分表示雨水)。

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


2 分析

通过观察,我们知道,要计算接的水,我们要找到能够存水的凹槽:

我们将这些存水的凹槽的边缘连接起来,可以发现,折线图的总体趋势是从低到高,从高到低(下图是随机生成的不同高度下的存水凹槽边缘图,以及其连线)

在这里插入图片描述

绘图代码已经在附录1中给出,可以直接运行,随机生成数据以及查看绘图。

那么我们能做的就是从左到右,依次找到越来越高的值;保存其索引,从右到左,依次找到越来越高的值,保存其索引。然后计算这些索引之间的最大盛水面积,减去之间的柱子的面积,就是最后的接雨水的结果
在这里插入图片描述

2.1 左到右

while start < len(height) and height[start] == 0: # 指针不断右移,跳过为0的元素start = start + 1
if start >= len(height) - 1: # 要是全为0,return 0return 0
lists.append(height[start]) # 保存值
indexes.append(start) # 保存索引
for i in range(start + 1, len(height)):if height[i] >= lists[-1]: # 比上一个凹槽边缘大或者等于,保存lists.append(height[i])indexes.append(i)

2.2 右到左

# 注意从右到左,不要超过左到右的边界indexes[-1],while end > indexes[-1] and height[end] == 0: end = end - 1 
# 而且从左到右已经判断完全0了,接下来不用判断了
reverse_lists.append(height[end])
reverse_indexes.append(end)
for i in range(end - 1, indexes[-1] - 1, -1): # 从右到左,注意边界
# 注意range(end - 1, indexes[-1] - 1, -1),举个例子,如果要生成一个10~0的
# 序列,则为range(10, -1, -1),我们知道range的前两个参数为范围,前闭后开,[10,-1)
# 第二个-1为step,表示按照反向遍历。if height[i] >= reverse_lists[-1]:reverse_lists.append(height[i])reverse_indexes.append(i)

2.3 计算面积

最直接的想法是,直接分开计算面积:
在这里插入图片描述

l_res = 0
for i in range(1, len(lists)):l = indexes[i - 1]r = indexes[i]l_res = l_res + (r - l - 1) * (min(height[l], height[r])) # 高度最小值乘以长度,# 长度为(right - left - 1)for j in range(l + 1, r):l_res = l_res - height[j] # 减去中间的面积for i in range(len(reverse_indexes) - 2, -1, -1): # 反过来遍历r = reverse_indexes[i]l = reverse_indexes[i + 1]l_res = l_res + (r - l - 1) * (min(height[l], height[r]))for j in range(l + 1, r):l_res = l_res - height[j]
return l_res

为了简单计算,首先我们将两个索引合并,

l_res = 0
# 将indexes和reversed(reverse_indexes)合并
indexes.extend(reversed(reverse_indexes))

在上面的图中,我们看到,两边的索引(左到右:[0, 3, 5],右到左:[19, 16, 11, 7, 5])有重叠,合并以后变成了[0, 3, 5, 5, 7, 11, 16, 19]怎么办?

无所谓,重叠之后长度为0,二者之间的面积还是0,不会对最终的面积有啥影响。

那么最后计算面积的过程为:

for i in range(1, len(indexes)):l = indexes[i - 1]r = indexes[i]l_res = l_res + max((r - l - 1), 0) * (min(height[l], height[r]))for j in range(l + 1, r):l_res = l_res - height[j]
return l_res

3 代码

3.1 Java

class Solution {public int trap(int[] height) {if (height.length <= 1) return 0;List<Integer> lists = new ArrayList<>();List<Integer> indexes = new ArrayList<>();List<Integer> reverse_lists = new ArrayList<>();List<Integer> reverse_indexes = new ArrayList<>();int start = 0;int end = height.length - 1;while(start < height.length && height[start] == 0) start++;if (start >= height.length - 1) return 0;lists.add(height[start]);indexes.add(start);for (int i = start + 1; i < height.length; i++) {if (height[i] >= lists.get(lists.size() - 1)) {lists.add(height[i]);indexes.add(i);}}int l_res = 0;for (int i = 1; i < lists.size(); i++) {int l = indexes.get(i - 1);int r = indexes.get(i);l_res += (r - l - 1) * (Math.min(height[l], height[r]));for (int j = l + 1; j < r; j++) {l_res -= height[j];}}while(end > indexes.get(indexes.size() - 1) && height[end] == 0) end--;reverse_lists.add(height[end]);reverse_indexes.add(end);for (int i = end - 1; i >= indexes.get(indexes.size() - 1); i--) {if (height[i] >= reverse_lists.get(reverse_lists.size() - 1)) {reverse_lists.add(height[i]);reverse_indexes.add(i);}}for (int i = reverse_indexes.size() - 2; i >=0; i--) {int r = reverse_indexes.get(i);int l = reverse_indexes.get(i + 1);l_res += (r - l - 1) * (Math.min(height[l], height[r]));for (int j = l + 1; j < r; j++) {l_res -= height[j];}}return l_res;}
}

3.2 Python

class Solution(object):# python 代码def trap(self, height):""":type height: List[int]:rtype: int"""if len(height) <= 1:return 0lists = []indexes = []reverse_lists = []reverse_indexes = []start = 0end = len(height) - 1while start < len(height) and height[start] == 0:start = start + 1if start >= len(height) - 1:return 0lists.append(height[start])indexes.append(start)for i in range(start + 1, len(height)):if height[i] >= lists[-1]:lists.append(height[i])indexes.append(i)while end > indexes[-1] and height[end] == 0:end = end - 1reverse_lists.append(height[end])reverse_indexes.append(end)for i in range(end - 1, indexes[-1] - 1, -1):if height[i] >= reverse_lists[-1]:reverse_lists.append(height[i])reverse_indexes.append(i)l_res = 0# 将indexes和reversed(reverse_indexes)合并indexes.extend(reversed(reverse_indexes))for i in range(1, len(indexes)):l = indexes[i - 1]r = indexes[i]l_res = l_res + max((r - l - 1), 0) * (min(height[l], height[r]))for j in range(l + 1, r):l_res = l_res - height[j]return l_res

在这里插入图片描述

附录1

# python 代码
def trap(height):""":type height: List[int]:rtype: int"""if len(height) <= 1:return 0lists = []indexes = []reverse_lists = []reverse_indexes = []start = 0end = len(height) - 1while start < len(height) and height[start] == 0:start = start + 1if start >= len(height) - 1:return 0lists.append(height[start])indexes.append(start)for i in range(start + 1, len(height)):if height[i] >= lists[-1]:lists.append(height[i])indexes.append(i)while end > indexes[-1] and height[end] == 0:end = end - 1reverse_lists.append(height[end])reverse_indexes.append(end)for i in range(end - 1, indexes[-1] - 1, -1):if height[i] >= reverse_lists[-1]:reverse_lists.append(height[i])reverse_indexes.append(i)l_res = 0# 将indexes和reversed(reverse_indexes)合并history_indexes = indexes.copy()indexes.extend(reversed(reverse_indexes))for i in range(1, len(indexes)):l = indexes[i - 1]r = indexes[i]l_res = l_res + max((r - l - 1), 0) * (min(height[l], height[r]))for j in range(l + 1, r):l_res = l_res - height[j]return l_res, history_indexes, reverse_indexesdef draw_pic(water, indexes, reverse_indexes):indexes.extend(reverse_indexes)indexes = list(set(indexes))indexes.sort()# 绘制折线图,x轴为indexes,y轴为water[indexes]plt.plot(indexes, [water[i] for i in indexes])plt.scatter(indexes, [water[i] for i in indexes])# 将water绘制成柱状图plt.bar(range(len(water)), water, color='yellow', zorder=1, edgecolor='black', linewidth=1)# 将indexes绘制成柱状图,绿色plt.bar(indexes, [water[i] for i in indexes], color='g', zorder=100, edgecolor='black', linewidth=1)# 设置 x 轴刻度及标签plt.xticks(np.arange(0, 20), range(0, 20))plt.show()# 生成一个更长的测试用例
import random
random.randint(0, 10)
water = [random.randint(0, 10) for _ in range(20)]res = trap(water)
indexes = res[1]
reverse_indexes = res[2]
draw_pic(water, indexes, reverse_indexes)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/173710.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何避免光模块接口受到污染?

光模块作为光通信领域一个重要的配件&#xff0c;实现光电和电光的转换&#xff0c;和光纤连接&#xff0c;承载了数据流量的快速转换与传输。因而在整个网络体系中&#xff0c;起着至关重要的作用。虽然光模块在使用过程中&#xff0c;不像交换机和服务器等网络设备一样需要经…

MacOS14 Sonoma 安装 Flutter 开发环境

本文针对 小白用户也包括自己&#xff0c;以前都是将这些写入我的有道云笔记。为了让给多人看见或者说自己更好的浏览&#xff0c;先将其记录如下。 朋友介绍一个项目说要开发一款App&#xff0c;最近也是闲着就答应下来。主要功能是通过蓝牙BLE控制设备的一个 Iot边缘设备&…

echarts 自定义提示样式

在setOption中添加自定义样式 tooltip: {trigger: axis,formatter: (params)> {// console.log(params);var result if(params[0] && params[1]){result 发电量对比<div style"background:#F4F7FC;padding:5px;margin:5px 0px;border-radius:6px"&…

如何在vs2017及以前版本(vs2010、vs2015)上添加 添加类型库中的MFC类

有时候当我们新建MFC工程需要使用到微软的一些自带控件&#xff0c;如播放视频要用到Windows media player控件&#xff0c;这时&#xff0c;我们可以通过添加“ActiveX控件中的mfc类(A)”这一选项. 还有有时候我们需要用到“类型库中的MFC类(T)及“MFC ODBC使用者(O)”。那我们…

记录本地与服务器之间数据传输方法(上传、下载文件)

文章目录 一、使用scp命令实现参数说明示例说明 二、使用工具实现windows系统苹果系统如有启发&#xff0c;可点赞收藏哟~ 一、使用scp命令实现 scp 是 secure copy &#xff08;安全复制&#xff09;的缩写, scp 是基于 ssh 登陆进行安全的远程文件拷贝命令。相当于 cp 命令 …

2020年06月 Scratch(四级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共15题,每题2分,共30分) 第1题 执行下图程序后,“花名”列表的第3项是? A:莲花 B:丁香 C:合欢 D:月季 答案:C 列表基本知识,选C。 第2题 执行如下图所示程序后,其结果为? A: B:

《算法通关村——解析堆在合并K个排序链表的应用》

《算法通关村——解析堆在合并K个排序链表的应用》 23. 合并 K 个升序链表 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 示例 1&#xff1a; 输入&#xff1a;lists [[1,4,5],[1,3,4],[2…

Node——事件的监听与触发

Node.js是由事件驱动的&#xff0c;每个任务都可以当作一个事件来处理&#xff0c;本贴将对Node.js中的events模块及其中处理事件的类EventEmitter的使用进行详细讲解。 1、EventEmitter对象 在JavaScript中&#xff0c;通过事件可以处理许多用户的交互&#xff0c;比如鼠标…

应用Web3.0的5种方法提升你的点击量

Web3.0早已成为互联网的全新方向标&#xff0c;为用户带来全新的手机上网感受。它也变成吸引住点击量疯涨的秘密武器。我们将要详细介绍Web3.0的五种使用方法&#xff0c;帮助你更好的了解并应用Web3.0技术性&#xff0c;以提升你的点击量。 1.可靠的身份认证Web3.0技术性提供了…

【23真题】罕见211!数一配英二!

今天分享的是23年合肥工业大学833的信号与系统数字信号处理试题及解析。合工大833考数一英二&#xff0c;这样的搭配还是很少见的。 本套试卷难度分析&#xff1a;22年合肥工业大学833考研真题&#xff0c;我也发布过&#xff0c;若有需要&#xff0c;戳这里自取!平均分为80和…

解析实人认证API的工作原理与应用场景

引言 随着数字化时代的不断发展&#xff0c;实人认证技术在各个领域中发挥着越来越重要的作用。其中&#xff0c;实人认证API作为一种先进的技术手段&#xff0c;通过输入姓名、身份证号码和一张人脸照片&#xff0c;与公安库身份证头像进行权威比对&#xff0c;从而返回比对分…

Clion取消double shift(按两下shift键)全局搜索

Clion 取消 double shift&#xff08;按两下 shift 键&#xff09;全局搜索。 如下图所示打开 setting。 点击 advanced setting&#xff0c;搜索 disable&#xff0c;取消勾选左侧复选框&#xff0c;点击 ok。

瑞数五代ast反混淆笔记一

第一部分 瑞数五代ast反混淆笔记一 文章目录 前言一、分析第一层js文件二、转换为switch-case三、效果图总结 前言 瑞数五代的反混淆做了很久了&#xff0c;当时写的很复杂&#xff0c;也没有记笔记&#xff0c;现在看代码都看不懂了&#xff0c;重新归顺下逻辑思路 一、分析第…

怎么做excel表格的二维码?文件快速做二维码的教程

Excel表格怎么做成二维码来扫码插看呢&#xff1f;Excel是工作中常用的一种文件格式&#xff0c;想要将表格内容分享给其他人查看&#xff0c;那么将表格生成二维码的方法会更加的方便快捷&#xff0c;其他人只需要扫描二维码就可以查看或者下载文件。表格excel二维码可以通过文…

如何找出excel中两列数据中不同的值(IF函数的用法)

第一部分&#xff0c;举例&#xff1a; 例1&#xff1a; 如下图所示&#xff0c;A列和B列是需要比较的数据&#xff0c;C列为对比规则&#xff1a;IF(A2B2,"是","否") 示例图 例2&#xff1a;给B列的成绩评等级 C列的规则&#xff1a; IF(B2>85,&qu…

【一周安全资讯1125】《工业和信息化领域数据安全行政处罚裁量指引 (试行)》公开征求意见;中国台湾大江生医泄露236GB数据

要闻速览 1、《工业和信息化领域数据安全行政处罚裁量指引 (试行)》公开征求意见 2、年度最大安全事件&#xff1a;MOVEit黑客攻击波及2600多家企业 3、美国核研究实验室遭黑客入侵&#xff0c;数十万个人数据泄漏 4、大英图书馆遭受勒索攻击&#xff0c;业务完全恢复需要数周…

Matplotlib画图接口_Python数据分析与可视化

Matplotlib画图接口 导入matplotlib显示图像画图接口 导入matplotlib 和numpy,pandas一样&#xff0c;在导入matplotlib时我们也可以用一些常用的简写形式&#xff1a; import matplotlib as mpl import matplotlib.pyplot as pltpyplot是最常用的画图模块接口&#xff0c;功…

哈希表、哈希冲突解决办法

文章目录 一、什么是哈希表&#xff1f;二、什么是哈希冲突&#xff1f;怎样解决&#xff1f;三、哈希表的大小为什么是质数&#xff1f;四、链表法五、开放地址法线性探测法平方探测法双哈希(Double Hashing) 六、哈希表满了怎么办&#xff1f;七、完美哈希八、一些使用哈希解…

机器学习基础Matplotlib绘图

一、运行环境 学习工具&#xff1a;jupyter-notebookpython版本&#xff1a;311系统&#xff1a;Win11 二、什么是matplotlib&#xff1f; matplotlib是基于python生态开发的一个可视化绘图库&#xff0c;它的出现让python在数据分析及机器学习方面占了重要的一部分&#…

springBoot的实现原理;SpringBoot是什么;使用SpringBoot的核心功能;springBoot核心注解以及核心配置文件

文章目录 springBootspringBoot的实现原理什么是 Spring Boot&#xff1f;SpringBoot是什么为什么要使用springBootSpring Boot的核心功能Spring Boot 主要有如下优点&#xff1a; SpringBoot启动过程-流程Spring Boot 的核心注解是哪个&#xff1f;什么是 JavaConfig&#xff…