[leetcode] 1488. Avoid Flood in The City

Description

Your country has an infinite number of lakes. Initially, all the lakes are empty, but when it rains over the nth lake, the nth lake becomes full of water. If it rains over a lake which is full of water, there will be a flood. Your goal is to avoid the flood in any lake.

Given an integer array rains where:

  • rains[i] > 0 means there will be rains over the rains[i] lake.

  • rains[i] == 0 means there are no rains this day and you can choose one lake this day and dry it.
    Return an array ans where:

  • ans.length == rains.length

  • ans[i] == -1 if rains[i] > 0.

  • ans[i] is the lake you choose to dry in the ith day if rains[i] == 0.

If there are multiple valid answers return any of them. If it is impossible to avoid flood return an empty array.

Notice that if you chose to dry a full lake, it becomes empty, but if you chose to dry an empty lake, nothing changes. (see example 4)

Example 1:

Input: rains = [1,2,3,4]
Output: [-1,-1,-1,-1]
Explanation: After the first day full lakes are [1]
After the second day full lakes are [1,2]
After the third day full lakes are [1,2,3]
After the fourth day full lakes are [1,2,3,4]
There's no day to dry any lake and there is no flood in any lake.

Example 2:

Input: rains = [1,2,0,0,2,1]
Output: [-1,-1,2,1,-1,-1]
Explanation: After the first day full lakes are [1]
After the second day full lakes are [1,2]
After the third day, we dry lake 2. Full lakes are [1]
After the fourth day, we dry lake 1. There is no full lakes.
After the fifth day, full lakes are [2].
After the sixth day, full lakes are [1,2].
It is easy that this scenario is flood-free. [-1,-1,1,2,-1,-1] is another acceptable scenario.

Example 3:

Input: rains = [1,2,0,1,2]
Output: []
Explanation: After the second day, full lakes are  [1,2]. We have to dry one lake in the third day.
After that, it will rain over lakes [1,2]. It's easy to prove that no matter which lake you choose to dry in the 3rd day, the other one will flood.

Example 4:

Input: rains = [69,0,0,0,69]
Output: [-1,69,1,1,-1]
Explanation: Any solution on one of the forms [-1,69,x,y,-1], [-1,x,69,y,-1] or [-1,x,y,69,-1] is acceptable where 1 <= x,y <= 10^9

Example 5:

Input: rains = [10,20,20]
Output: []
Explanation: It will rain over lake 20 two consecutive days. There is no chance to dry any lake.

Constraints:

  • 1 <= rains.length <= 10^5
  • 0 <= rains[i] <= 10^9

分析

题目的意思是:给你一个数组,数组里面的大于0的值代表湖的编号,并且表示洪水填满了整个湖,0值表示可以让前面的湖水清空。请问是否存在一种组合使得湖避免发大水,即同一个湖被填满了至多一次。这道题我也没什么思路,我大概解释一下别人的思路,fill_lakes用来存放湖的编号和位置映射的,dry_days用来存放清空的索引的,现在遍历数组,如果遍历的数大于0,则需要进一步判断该湖是否曾经被填满过,如果曾经被填满,则看有没有清空的索引能够把当前被填满的湖清空,如果能清空,则删除一个合法的清空索引,给res相应清空的位置填入当前的lake索引,保存新的湖的位置索引;否则返回空。如果遍历的数等于0,则加入到dry_days集合中,然后把res相应的位置设置为99999,因为还不确定填什么数,所以就指定了一个比较大的数.

代码

class Solution:
    def avoidFlood(self, rains: List[int]) -> List[int]:
        fill_lakes={}
        dry_days=[]
        res=[]
        for day,lake in enumerate(rains):
            if(lake):
                res.append(-1)
                if(lake in fill_lakes):
                    last_rain_day=fill_lakes[lake]
                    valid_dry_day=-1
                    for dry_day in dry_days:
                        if(dry_day >last_rain_day):
                            valid_dry_day=dry_day
                            break
                    if(valid_dry_day>0):
                        dry_days.remove(valid_dry_day)
                        fill_lakes[lake]=day
                        res[valid_dry_day]=lake
                    else:
                        return []
                else:
                    fill_lakes[lake]=day
            else:
                dry_days.append(day)
                res.append(99999)
        return res

参考文献

[LeetCode] Python 3 Solution Explained

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

农民小飞侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值