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

3D 版接雨水

3D 版接雨水

这道题目在面试的时候比较热门,所以单拿出这道题目进行一次学习记录。原题的链接是:407. 接雨水 II。

题目描述

思路

其实和 2D 接雨水类似,3D 接雨水也要将每一个格子作为最终统计答案的单位,计算每一个格子存储最多的水时高度是多少。假如我们以water[i][j]来代表坐标点(i, j)位置最多可以存储的水的高度,那么最终这个单位对答案的贡献值就是water[i][j] - heightMap[i][j],此处的heightMap是题目的输入,记录的就是每一个单元格的高度。

这道题的解题思路参考自 LeetCode 官方的题解,使用广搜的思路来解决这个问题。

首先我们要做的就是找到heightMap当中的最高点maxHeight,并假设初始时所有的格子可存放的水的高度都是maxHeight。显然,这对于处在边界上的格子来说是不现实的,因为它们无法存储任何的水,所有的水都会从边界流下去。因此,在设置完water[i][j] = maxHeight之后,我们首先对边界的状态进行维护。

具体来说,我们需要判断的是,边界状态的water[i][j]是否高于heightMap[i][j],如果是的话,就说明这个格子存储的水溢出了,将状态修复为water[i][j] = heightMap[i][j],并将这个坐标存储到一个队列q当中,用于后续的广搜。

解决这道题目的关键就在于队列的使用,方才我们首先维护的是边界上格子的状态,这就意味着所有有水溢出的格子都将会对接下来中间格子的存储水的状态产生影响。

为了更好地理解上面这段话,我们可以看下面这张图:

如果此时存储水的方格边界上出现了一个缺口,那么以这个缺口为起点,其中所有可达的方格的状态都会产生改变。

将边界的状态存储到队列q当中之后,我们就可以开始进行广搜了。具体来说,每一次取队首的一个元素,它是一个二维坐标,我们要判断的是它周围的四个合法的(不超出边界)坐标是否需要进行维护。

是否需要进行维护,就需要我们进行进一步的判断了,这个判断条件也是解决这道题的关键。假设我们从队首取出的元素的坐标是(x, y)(nx, ny)是其一跳之内上下左右四个方向的新的合法位置。如果water[nx][ny] > water[x][y],就说明这个位置存储水的高度比当前位置还要高,如果同时满足water[nx][ny] > heightMap[nx][ny],就说明(nx, ny)这个位置的水溢出了。因为:

  • water[nx][ny] > water[x][y]代表(x, y)这个位置相邻的一个位置(nx, ny)的存水量比它高,假设heightMax[nx][ny],也就是(nx, ny)的墙体的高度比存水量要低,那么water[nx][ny]的水一定会流向water[x][y],进一步流向更低的位置,最终从边界流出去;
  • water[nx][ny] > heightMap[nx][ny]进一步说明(nx, ny)这个位置的存水量确实比墙体的高度还要高,如果water[nx][ny] == heightMap[nx][ny],就说明这个位置其实是一个墙体,它的存水量为water[nx][ny] - heightMap[nx][ny] == 0

满足上述两个条件,就说明(nx, ny)这个位置的水存不住了,需要维护它的状态,也就是water[nx][ny] = max(water[x][y], heightMap[nx][ny])。状态维护的方程很好理解,要么这个位置的水位线与它的邻格(x, y)平齐,要么所有水全部流走了,水位线高度降至墙体的高度。同时将(nx, ny)这个位置加入到队列当中,用于对它的邻居的状态进行维护。

最后,基于waterheightMap两个二维数组统计最终的答案即可。

Golang 代码

func trapRainWater(heightMap [][]int) int {// 首先找到最高的高度maxHeight := 0m, n := len(heightMap), len(heightMap[0])for i := 0; i < m; i ++ {for j := 0; j < n; j ++ {maxHeight = max(maxHeight, heightMap[i][j])}}// 之后初始化一个 water 二维数组, 记录每一个格子的水最高可以存多高water := make([][]int, m)for i := 0; i < m; i ++ {water[i] = make([]int, n)for j := 0; j < n; j ++ {// 初始化所有格子的高度为最高的 maxHeightwater[i][j] = maxHeight}}type loc struct {x, y int}q := []loc{}    // 初始化一个队列, 存储的是格子的二维坐标for i := 0; i < m; i ++ {for j := 0; j < n; j ++ {if i == 0 || i == m - 1 || j == 0 || j == n - 1 {if water[i][j] > heightMap[i][j] {// 首先对边界上的格子进行维护, 再逐渐推到里面water[i][j] = heightMap[i][j]q = append(q, loc{i, j})}}}}// 维护一个队列, 如果某个格子的水的高度发生了变化, 应当告知周围的格子并改变状态dx, dy := []int{0, 0, 1, -1}, []int{1, -1, 0, 0}for len(q) > 0 {p := q[0]; q = q[1:]x, y := p.x, p.yfor i := 0; i < 4; i ++ {nx, ny := x + dx[i], y + dy[i]if nx < 0 || nx >= m || ny < 0 || ny >= n {continue}if water[x][y] < water[nx][ny] && heightMap[nx][ny] < water[nx][ny] {water[nx][ny] = max(water[x][y], heightMap[nx][ny])q = append(q, loc{nx, ny})}}}// 统计答案ans := 0for i := 0; i < m; i ++ {for j := 0; j < n; j ++ {ans += water[i][j] - heightMap[i][j]}}return ans
}

文章转载自:

http://zZACKICh.srgyj.cn
http://jqUqOQpU.srgyj.cn
http://KHVNmwzm.srgyj.cn
http://RiYiB8Ij.srgyj.cn
http://MoUZ1Gjx.srgyj.cn
http://87uWFIcL.srgyj.cn
http://QM0zWiIK.srgyj.cn
http://zOQNQQWD.srgyj.cn
http://PEEYvBrZ.srgyj.cn
http://yWHQUOgA.srgyj.cn
http://RaEBsjVy.srgyj.cn
http://DOQQfD6B.srgyj.cn
http://BBNBEDdP.srgyj.cn
http://KlK3wR0N.srgyj.cn
http://inq0nk89.srgyj.cn
http://6mxvUY8u.srgyj.cn
http://2r5LIRTk.srgyj.cn
http://0usXiqsJ.srgyj.cn
http://vlTmhBkp.srgyj.cn
http://GhK0G3GM.srgyj.cn
http://vMAaVRdz.srgyj.cn
http://NJhfxjz2.srgyj.cn
http://qcYDMSKy.srgyj.cn
http://2D9cHB2M.srgyj.cn
http://9boGJ0P4.srgyj.cn
http://dL2cYlfo.srgyj.cn
http://B4DXGhRC.srgyj.cn
http://ELvdz0XY.srgyj.cn
http://kGa7rpn5.srgyj.cn
http://2D9LJqfK.srgyj.cn
http://www.dtcms.com/a/372173.html

相关文章:

  • (LeetCode 每日一题)1304. 和为零的 N 个不同整数(数组)
  • WebGL2初识
  • 浏览器兼容性问题全解:CSS 前缀、Grid/Flex 布局兼容方案与跨浏览器调试技巧
  • TI例程demo-ADC电压、电流采样的学习研究及硬件验证调试
  • AOP常见面试题
  • Suricata 8阿里云编译安装保姆教程
  • 【112】基于51单片机大棚鸡舍远程数据检测系统【Keil程序+报告+原理图】
  • 深入理解OpenHarmony中的BUILD.gn:从语法到模块化构建
  • 阴阳学:从入门到精通
  • vulhub通关笔记1—docker unauthorized-rce
  • ZYNQ PS XADC读取芯片内部温度值,电压值。
  • 每日一题(3)
  • 泛型编程(简单介绍,通俗易懂)
  • 扩散模型揭秘:生成式AI的核心与应用
  • 【Flink】Flink Runtime 架构设计
  • MySQL数据库同步
  • 使用 Spring Security 实现 OAuth2:一步一步的操作指南
  • Axure: 分组柱状图1
  • CEEMDAN-PSO-CNN-GRU 锂电池健康状态预测matlab
  • Spring Cloud Gateway 作为一个独立的服务进行部署吗
  • webrtc弱网-LossBasedBweV2类源码分析与算法原理
  • leetcode hot100 二叉搜索树
  • 杂学项目1、S32K144与上位机通信
  • GitHub自动化利器:Probot框架实战指南
  • 一款没有任何限制的免费远程手机控制手机的软件简介
  • 企云网多应用授权系统源码 正版查询系统源码
  • Windows netstat 命令使用说明
  • 软件工程:DO-178中的适航要求核心要素
  • Caffeine Count-Min Sketch TinyLFU实现:FrequencySketch
  • 【系统分析师】第7章-基础知识:软件工程(核心总结)