程序员必知:【LeetCode】PourWater倒水

简介: 程序员必知:【LeetCode】PourWater倒水

We are given an elevation map, heights【i】 representing the height of the terrain at that index. The width at each index is 1. After V units of water fall at index K, how much water is at each index?

Water first drops at index K and rests on top of the highest terrain or water at that index. Then, it flows according to the following rules:

If the droplet would eventually fall by moving left, then move left.

Otherwise, if the droplet would eventually fall by moving right, then move right.

Otherwise, rise at it's current position.

Here, "eventually fall" means that the droplet will eventually be at a lower level if it moves in that direction. Also, "level" means the height of the terrain plus any water in that column.

We can assume there's infinitely high terrain on the two sides out of bounds of the array. Also, there could not be partial water being spread out evenly on more than 1 grid block - each unit of water has to be in exactly one block.

Example 1:

Input: heights = 【2,1,1,2,1,2,2】, V = 4, K = 3

Output: 【2,2,2,3,2,2,2】

Explanation:

# #

# #

## # ###

#########

0123456 <- index

The first drop of water lands at index K = 3:

# #

# w #

## # ###

#########

0123456

When moving left or right, the water can only move to the same level or a lower level.

(By level, we mean the total height of the terrain plus any water in that column.)

Since moving left will eventually make it fall, it moves left.

(A droplet "made to fall" means go to a lower height than it was at previously.)

# #

# #

## w# ###

#########

0123456

Since moving left will not make it fall, it stays in place. The next droplet falls:

# #

# w #

## w# ###

#########

0123456

Since the new droplet moving left will eventually make it fall, it moves left.

Notice that the droplet still preferred to move left,

even though it could move right (and moving right makes it fall quicker.)

# #

# w #

## w# ###

#########

0123456

# #

# #

##ww# ###

#########

0123456

After those steps, the third droplet falls.

Since moving left would not eventually make it fall, it tries to move right.

Since moving right would eventually make it fall, it moves right.

# #

# w #

##ww# ###

#########

0123456

# #

# #

##ww#w###

#########

0123456

Finally, the fourth droplet falls.

Since moving left would not eventually make it fall, it tries to move right.

Since moving right would not eventually make it fall, it stays in place:

# #

# w #

##ww#w###

#########

0123456

The final answer is 【2,2,2,3,2,2,2】:

#

#######

#######

0123456

Example 2:

Input: heights = 【1,2,3,4】, V = 2, K = 2

Output: 【2,3,3,4】

Explanation:

The last droplet settles at index 1, since moving further left would not cause it to eventually fall to a lower height.

Example 3:

Input: heights = 【3,1,3】, V = 5, K = 1

Output: 【4,4,4】

Note:

heights will have length in 【1, 100】 and contain integers in 【0, 99】.

V will be in range 【0, 2000】.

K will be in range 【0, heights.length - 1】.

这道题说有不同高度的地面,每次都位置K有水滴落下,水滴落下后移动的方向有如下的规则:

1. 如果水滴向左移动后最终停止的位置低于落下的位置,则向左移动。

2. 否则若水滴向右移动后最终停止的位置低于落下的位置,则向右移动。

3. 否则停在原来的位置。

水滴停止后,原来的位置高度就增加1,让我们返回最后地面的高度。我们首先来分析题目中的例子1:

# #

# 4 #

##21#3###

#########

我们可以观察出,如果左边到的位置低的话,就先去左边,即便右边能到同样低的位置,也还是左边优先。但是这个例子没能说明,如果右边的位置更低的话,是去右边呢,还是左边,看下面这个例子:

54# #

32### ###

1##### #####

#############

红色表示水滴落下的位置,我们可以看到第五滴水没有去右边更低的地方,而是去了左边的位置,这说明,左边有至高优先权,只要左边的最终位置低于水滴落下的位置,一定会去左边。

还有就是,去一个方向最终要落到一个局部最低点,请看下面这个例子:

#

###1# #

##### #

#######

我们可以看到,水滴去了右边第一个局部最低点,而再右边的全局最低点是无法到达的。如果都是一样的高度的话,落在离水滴落下起始位置最近的点,请看下下面这两个例子:

#

###1#

#####

#1

#####

#####

第一个例子中水滴去了局部最低点,第二个例子中由于右边的高度都相同,水滴去了最靠近起始位置的点。

那么分析到这里,我想思路应该比较明晰了吧。首先我们尝试向左走,找到第一个局部最低点,停止条件是左边的高度大于当前高度,但是为了防止出现大家高度都一样而需要停止在靠近起始点位置的情况,我们来一个回滚操作,就是只要和右边的高度一样,就一直往右滚。同样,在尝试向右走,找第一个局部最低点,停止条件是右边的高度大于当前高度,但是为了防止出现大家高度都一样而需要停止在靠近起始点位置的情况,我们也来一个回滚操作,就是只要和左边的高度一样,就一直往左滚。那么此时我们来做比较,如果左边的局部最低点小于雨滴落下位置的高度,那么左边局部最低点高度自增1。否则如果右边的局部最低点高度小于雨滴落下位置的高度,则右边局部最低点高度自增1。如果左右高度都一样,则雨滴落下位置的高度自增1,参见代码如下:

class Solution {

public:

vector[span style="color: rgba(0, 0, 255, 1)">intint

for (int i = 0; i < V; ++i) {

int l = K, r = K, n = heights.size();

while (l > 0 heights【l】 >= heights【l - 1】) --l;

while (l < K heights【l】 == heights【l + 1】) ++l;

while (r < n - 1 heights【r】 >= heights【r + 1】) ++r;

while (r > K heights【r】 == heights【r - 1】) --r;

(heights【l】 < heights【K】) ? ++heights【l】 : ++heights【r】;

}//代码效果参考:http://www.ezhiqi.com/zx/art_4856.html

return heights;

}//代码效果参考:http://www.ezhiqi.com/zx/art_7704.html

};

类似题目:

Trapping Rain Water

参考资料:

LeetCode All in One 题目讲解汇总(持续更新中...)

(欢迎加入博主的知识星球,博主将及时答疑解惑,并分享刷题经验与总结,快快加入吧~)

喜欢请点赞,疼爱请打赏??~.~

Venmo 打赏

相关文章
|
5月前
|
机器学习/深度学习 程序员
老程序员分享:leetcode笔记201.BitwiseANDofNumbersRange
老程序员分享:leetcode笔记201.BitwiseANDofNumbersRange
24 0
|
2月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
55 6
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 26. 树的子结构
这篇文章提供了解决LeetCode上"剑指Offer 26. 树的子结构"问题的Python代码实现和解析,判断一棵树B是否是另一棵树A的子结构。
50 4
|
3月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
113 2
|
17天前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
16 1
|
2月前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
3月前
|
索引 Python
【Leetcode刷题Python】从列表list中创建一颗二叉树
本文介绍了如何使用Python递归函数从列表中创建二叉树,其中每个节点的左右子节点索引分别是当前节点索引的2倍加1和2倍加2。
56 7
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 30. 包含min函数的栈
本文提供了实现一个包含min函数的栈的Python代码,确保min、push和pop操作的时间复杂度为O(1)。
27 4
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
52 5