【每日一题】避免洪水泛滥

Tag

【贪心+二分】【数组】【2023-10-13】


题目来源

1488. 避免洪水泛滥


题目解读

现在有一些湖泊,在下雨的时候会向指定的湖泊中下雨,一旦下雨湖泊就会满。如果某个湖泊第二次下雨了,那么该湖泊就会发大水,我们需要在晴天的时候提前给一些湖泊排水,现在需要求的是在晴天的时候给哪些湖泊排水。

题目是有一点点不好理解的,只能多看看几遍,分析分析例子以便快速理解。

官方示例


解题思路

方法一:贪心+二分

使用一个哈希 lastIdx 表来记录湖泊上一次下雨的时间,现在遍历到的湖泊是 rains[i],如果之前已经遍历过了湖泊 rains[i],那么该湖泊这次就会发大水。为了避免发大水,需要在已经记录的晴天当中拿出一天的时间来给 rains[i] 湖泊排水,为了尽可能把排水机会留给其他的发大水的湖泊,我们选择给 rains[i] 排水的那一天为晴天中 >= i 的最小值。

实现代码

class Solution {
public:
    vector<int> avoidFlood(vector<int>& rains) {
        int n = rains.size();
        vector<int> res(n, 1);
        unordered_map<int, int> lastIdx;
        set<int> zeros;
        for (int i = 0; i < n; ++i) {
            if (rains[i] == 0) {
                zeros.insert(i);
            }
            else {
                res[i] = -1;
                if (lastIdx.count(rains[i])) {  // 之前遍历过
                    auto it = zeros.lower_bound(lastIdx[rains[i]]);
                    if (it == zeros.end()) {  // 两个湖泊下雨的时间之间没有晴天,没法排水
                        return {};
                    }
                    res[*it] = rains[i];
                    zeros.erase(it);
                }
                lastIdx[rains[i]] = i;
            }
        }
        return res;
    }
};

复杂度分析

时间复杂度: n l o g n nlogn nlogn n n n 为数组 rains 的长度。有序集合中每次的插入和查询时间为 O ( l o g n ) O(logn) O(logn)

空间复杂度: O ( n ) O(n) O(n),主要是有序集合和哈希表的时间开销。

其他语言

python3

from sortedcontainers import SortedList

class Solution:
    def avoidFlood(self, rains: List[int]) -> List[int]:
        res = [1] * len(rains)
        zeros = SortedList()
        lastIdx = {}
        for i, rain in enumerate(rains):
            if rain == 0:
                zeros.add(i)
            else:
                res[i] = -1
                if rain in lastIdx:
                    it = zeros.bisect(lastIdx[rain])
                    if it == len(zeros):
                        return []
                    res[zeros[it]] = rain
                    zeros.discard(zeros[it])
                lastIdx[rain] = i
        return res

写在最后

如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。

最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 👍 哦。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wang_nn

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

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

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

打赏作者

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

抵扣说明:

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

余额充值