【每日一题Day346】LC1488避免洪水泛滥 | 贪心+哈希表

简介: 【每日一题Day346】LC1488避免洪水泛滥 | 贪心+哈希表

避免洪水泛滥【LC1488】

你的国家有无数个湖泊,所有湖泊一开始都是空的。当第 n 个湖泊下雨前是空的,那么它就会装满水。如果第 n 个湖泊下雨前是 满的 ,这个湖泊会发生 洪水 。你的目标是避免任意一个湖泊发生洪水。

给你一个整数数组 rains ,其中:

rains[i] > 0 表示第 i 天时,第 rains[i] 个湖泊会下雨。

rains[i] == 0 表示第 i 天没有湖泊会下雨,你可以选择 一个 湖泊并 抽干 这个湖泊的水。

请返回一个数组 ans ,满足:

ans.length == rains.length

如果 rains[i] > 0 ,那么ans[i] == -1 。

如果 rains[i] == 0 ,ans[i] 是你第 i 天选择抽干的湖泊。

如果有多种可行解,请返回它们中的 任意一个 。如果没办法阻止洪水,请返回一个 空的数组 。

请注意,如果你选择抽干一个装满水的湖泊,它会变成一个空的湖泊。但如果你选择抽干一个空的湖泊,那么将无事发生。

思路:贪心+哈希表

  • 当如果某个湖泊在第i天和第j天会下雨,那么需要在没有湖泊下雨的第k天将该湖泊抽干,k ∈ ( i , j ) 贪心:为了避免其他湖泊发生湖水、即不影响将其他湖泊抽干,我们应该选择第一个大于i的索引作为k;

     如果没有合法的k,则证明没办法阻止洪水,返回一个 空的数组 。

  • 根据以上思路,我们需要以下数据结构实现
  • 哈希表:key为湖泊编号,value为湖泊在第几天下雨
  • TreeSet:记录哪天不下雨,可以抽干某个湖泊的水;使用API搜索大于给定元素的最小元素并删除给元素
  • 实现
class Solution {
    public int[] avoidFlood(int[] rains) {
        int n = rains.length;
        int[] ans = new int[n];
        Arrays.fill(ans, -1);
        TreeSet<Integer> days = new TreeSet<>();// 记录哪天可以抽干某个湖泊的水
        Map<Integer, Integer> fullPools = new HashMap<>();// key为湖泊编号,value为湖泊在第几天下雨
        for (int i = 0; i < n; i++){
            if (rains[i] == 0){
                days.add(i);
                ans[i] = 1;// 任意抽干一个湖泊
            }else if (fullPools.containsKey(rains[i])){
                // 湖泊已满,需要在fullPools.get(rains[i])之后抽干该湖泊
                Integer j = days.higher(fullPools.get(rains[i]));//返回此set中大于给定元素的最小元素,如果没有这样的元素,则返回NULL。
                if (j == null){
                    return new int[0];
                }else{
                    ans[j] = rains[i];
                    days.remove(j);
                    fullPools.put(rains[i], i);
                }           
            }else{
                fullPools.put(rains[i], i);
            }
        }
        return ans;
    }
}

复杂度

时间复杂度:O ( n l o g n )

空间复杂度:O ( n )

目录
相关文章
|
6月前
|
存储
【每日一题Day158】LC2395和相等的子数组 | 哈希表
【每日一题Day158】LC2395和相等的子数组 | 哈希表
30 0
|
6月前
|
存储
【每日一题Day113】LC1797设计一个验证系统 | 哈希表
【每日一题Day113】LC1797设计一个验证系统 | 哈希表
41 0
|
6月前
|
存储
【每日一题Day132】LC23633合并相似的物品 | 哈希表 排序+双指针
【每日一题Day132】LC23633合并相似的物品 | 哈希表 排序+双指针
51 0
|
6月前
|
机器学习/深度学习
【每日一题Day120】LC2341数组能形成多少数对 | 哈希表 排序
【每日一题Day120】LC2341数组能形成多少数对 | 哈希表 排序
38 0
|
6月前
【每日一题Day136】LC982按位与为零的三元组 | 哈希表
【每日一题Day136】LC982按位与为零的三元组 | 哈希表
62 0
|
6月前
【每日一题Day163】LC2367算术三元组的数目 | 二分查找 哈希表
【每日一题Day163】LC2367算术三元组的数目 | 二分查找 哈希表
29 0
|
6月前
|
算法
【每日一题Day229】LC2352相等行列对 | 哈希
【每日一题Day229】LC2352相等行列对 | 哈希
43 0
|
6月前
【每日一题Day340】LC2251花期内花的数目 | 差分+哈希表+排序 排序+二分查找
【每日一题Day340】LC2251花期内花的数目 | 差分+哈希表+排序 排序+二分查找
37 0
|
6月前
【每日一题Day118】LC1124表现良好的最长时间段 | 前缀和+单调栈/哈希表
【每日一题Day118】LC1124表现良好的最长时间段 | 前缀和+单调栈/哈希表
52 0
|
6月前
|
存储
【每日一题Day275】LC771宝石与石头 | 哈希表 状态压缩
【每日一题Day275】LC771宝石与石头 | 哈希表 状态压缩
43 0