【LeetCode:1488. 避免洪水泛滥 | 有序表 & 哈希表】

在这里插入图片描述

算法题

算法刷题专栏 | 面试必备算法 | 面试高频算法
越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨
作者简介:硕风和炜,CSDN-Java领域新星创作者,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验分享|好用的网站工具分享
恭喜你发现一枚宝藏博主,赶快收入囊中吧
人生如棋,我愿为卒,行动虽慢,可谁曾见我后退一步?

算法题

在这里插入图片描述

【LeetCode:1488. 避免洪水泛滥 | 有序表 & 哈希表】_第1张图片

目录

    • 题目链接
    • ⛲ 题目描述
    • 求解思路&实现代码&运行结果
      • ⚡ 有序表 & 哈希表
        • 求解思路
        • 实现代码
        • 运行结果
    • 共勉

题目链接

  • 1488. 避免洪水泛滥

⛲ 题目描述

你的国家有无数个湖泊,所有湖泊一开始都是空的。当第 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 天选择抽干的湖泊。
如果有多种可行解,请返回它们中的 任意一个 。如果没办法阻止洪水,请返回一个 空的数组 。

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

示例 1:

输入:rains = [1,2,3,4]
输出:[-1,-1,-1,-1]
解释:第一天后,装满水的湖泊包括 [1]
第二天后,装满水的湖泊包括 [1,2]
第三天后,装满水的湖泊包括 [1,2,3]
第四天后,装满水的湖泊包括 [1,2,3,4]
没有哪一天你可以抽干任何湖泊的水,也没有湖泊会发生洪水。
示例 2:

输入:rains = [1,2,0,0,2,1]
输出:[-1,-1,2,1,-1,-1]
解释:第一天后,装满水的湖泊包括 [1]
第二天后,装满水的湖泊包括 [1,2]
第三天后,我们抽干湖泊 2 。所以剩下装满水的湖泊包括 [1]
第四天后,我们抽干湖泊 1 。所以暂时没有装满水的湖泊了。
第五天后,装满水的湖泊包括 [2]。
第六天后,装满水的湖泊包括 [1,2]。
可以看出,这个方案下不会有洪水发生。同时, [-1,-1,1,2,-1,-1] 也是另一个可行的没有洪水的方案。
示例 3:

输入:rains = [1,2,0,1,2]
输出:[]
解释:第二天后,装满水的湖泊包括 [1,2]。我们可以在第三天抽干一个湖泊的水。
但第三天后,湖泊 1 和 2 都会再次下雨,所以不管我们第三天抽干哪个湖泊的水,另一个湖泊都会发生洪水。

提示:

1 <= rains.length <= 105
0 <= rains[i] <= 109

求解思路&实现代码&运行结果


⚡ 有序表 & 哈希表

求解思路
  1. 关于这道题目,暴力的解法是可以想到并且实现的,但是,肯定会超时,无法通过。因此,我们需要尝试另外一种解法。
  2. 遍历整个数组,如果此时的湖泊不会下雨,那么我们直接先将不会下雨的天气收集起来;但如果当前的湖泊是要下雨的,此时我们需要判断,之前的湖泊是否下过雨,如果没有下过,不会洪水泛滥,直接收集答案。如果下过的话,此时我们需要使用特权:可以选择一个湖泊并抽干这个湖泊的水,怎么实现呢?通过我们之前收集不会下雨的集合,在集合中快速找到,刚大于在该湖泊下过雨水晴天的位置下标,使用特权,将水抽干,收集答案。
  3. 这个过程需要使用到俩种数据结构,第一个是快速找到大于某一个数值的有序表,用来收集不会下雨的天气集合。第二个是HashMap集合,通过key维护第i个湖泊位置是否下雨,value维护此时所处的下标即可。
  4. 具体求解的过程步骤请看下面代码。
实现代码
class Solution {
    public int[] avoidFlood(int[] rains) {
        int n=rains.length;
        int[] res=new int[n];
        Arrays.fill(res,-1);
        TreeSet<Integer> set=new TreeSet<>();
        HashMap<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<n;i++){
            int r=rains[i];
            if(r>0){
                if(map.containsKey(r)){
                    Integer num=set.higher(map.get(r));
                    if(num==null) return new int[]{};
                    res[num]=r;
                    set.remove(num);
                }
                map.put(r,i);
            }else{
                set.add(i);
                res[i]=1;
            }
        }
        return res;
    }
}
运行结果

【LeetCode:1488. 避免洪水泛滥 | 有序表 & 哈希表】_第2张图片


共勉

最后,我想和大家分享一句一直激励我的座右铭,希望可以与大家共勉!

在这里插入图片描述

你可能感兴趣的:(LeetCode每日一题打卡,leetcode,算法,java,有序表,哈希表,hashmap,treeset)