755 倒水

题目描述:
给出一个地形高度图, heights[i] 表示该索引处的高度。每个索引的宽度为 1。在 V 个单位的水落在索引 K 处以后,每个索引位置有多少水?

水最先会在索引 K 处下降并且落在该索引位置的最高地形或水面之上。然后按如下方式流动:

如果液滴最终可以通过向左流动而下降,则向左流动。
否则,如果液滴最终可以通过向右流动而下降,则向右流动。
否则,在当前的位置上升。
这里,“最终下降” 的意思是液滴如果按此方向移动的话,最终可以下降到一个较低的水平。而且,“水平”的意思是当前列的地形的高度加上水的高度。

我们可以假定在数组两侧的边界外有无限高的地形。而且,不能有部分水在多于 1 个的网格块上均匀分布 - 每个单位的水必须要位于一个块中。

示例 1:
输入:heights = [2,1,1,2,1,2,2], V = 4, K = 3
输出:[2,2,2,3,2,2,2]
解释:
在这里插入图片描述
第一个水滴降落在索引 K = 3 上:
在这里插入图片描述
当向左或向右移动时,水可以移动到相同或更低的高度。When moving left or right, the water can only move to the same level or a lower level.
(从水平上看,意思是该列的地形高度加上水的高度)
由于向左移动可以最终下落,因此向左移动。
(一个水滴 “下落” 的意思是可以相比之前可以进入更低的高度)
在这里插入图片描述
由于向左移动不会使其降落,所以停在该位置上。下一个水滴下落:
在这里插入图片描述
由于新水滴向左移动可以最终下落,因此向左移动。
注意水滴仍然是优先选择向左移动,
尽管可以向右移动(而且向右移动可以下落更快)
在这里插入图片描述
经过刚才的阶段后,第三个水滴下落。
由于向左移动不会最终下落,因此尝试向右移动。
由于向右移动可以最终下落,因此向右移动。
在这里插入图片描述
最终,第四个水滴下落。
由于向左移动不会最终下落,因此尝试向右移动。
由于向右移动不会最终下落,因此停在当前位置:
在这里插入图片描述
最终的答案为 [2,2,2,3,2,2,2]:
在这里插入图片描述
示例 2:
输入:heights = [1,2,3,4], V = 2, K = 2
输出:[2,3,3,4]
解释:
最后的水滴落在索引 1 位置,因为继续向左移动不会使其下降到更低的高度。

示例 3:
输入:heights = [3,1,3], V = 5, K = 1
输出:[4,4,4]

注:
heights 的长度为 [1, 100] ,并且每个数的范围为[0, 99]。
V 的范围 [0, 2000]。
K 的范围 [0, heights.length - 1]。

方法1:
主要思路:
(1)按照题意,模拟水流动的过程;

class Solution {
public:
    vector<int> pourWater(vector<int>& heights, int V, int K) {
        while(V--){//每次低落一滴水,找出该水滴的位置
            int index=K-1;//先向左移动,找出合适的位置
            //找出更低的位置
            while(index>=0&&heights[index]<=heights[index+1]){
                --index;
            }
            //判断在左边是否找到更小的位置
            if(heights[++index]<heights[K]){
            	//将该高度下的位置尽量向右移动
                while(heights[index]==heights[index+1]){
                    ++index;
                }
                //在该位置加1
                ++heights[index];
                continue;
            }
			//判断右边的位置
            index=K+1;
            //找出右边的更低的位置
            while(index<heights.size()&&heights[index]<=heights[index-1]){
                ++index;
            }
            //判断右边的位置是否是有更低的位置
            if(heights[--index]<heights[K]){
            	//若有,尽量将该高度下的位置向左移动
                while(heights[index]==heights[index-1]){
                    --index;
                }
                //将该高度增加1
                ++heights[index];
                continue;
            }
            //否则,在给定的位置增加1
            ++heights[K];
        }
        return heights;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值