力扣周赛 第194场 5442. 避免洪水泛滥

题目

原题链接
你的国家有无数个湖泊,所有湖泊一开始都是空的。当第 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 长度相同的结果数组 ans
2.使用HashMap存储当前时间已满的湖泊,key为湖泊编号,value为下满该湖泊的时间;
3.使用queue存储未下雨的天数;
4.循环遍历rains数组:
5.如果当天不下雨,则记录至queue
6.如果当天下雨,且该湖泊已满,先将ans数组对应位置设为-1,,然后从queue中取出 该湖泊被下满之后的第一个位置
将ans数组的该天设置为该湖泊的编号;map中的记录修正为当前时间;如果遍历完了整
个队列找不到符合条件的不下雨时间,则返回一个空数组,函数结束。
7.如果当天下雨,该湖泊未满,先将ans数组对应位置设为-1,然后将湖泊编号和时间存入map
8.循环结束。
9.如果queue中仍有剩余元素,表示多余的不下雨的日子,根据题意将对应ans对应位置都设为1即可。
10.返回ans数组。

解析

主要比较复杂的部分在第六步。翻译成白话就是:遇到一天(比如第N天)下雨的,且要下雨的那个湖泊当前是满的。那么就需要往前推,找到这个湖泊被下满之后的不下雨的第一天,在那天把这个湖泊抽干,以应对第N天的雨水。那么到了第N天之后,这个湖泊其实还是满的,下满的时间也更新到了第N天。

代码

    public  int[] avoidFlood(int[] rains) {
        HashMap<Integer, Integer> map = new HashMap<>();
        LinkedList<Integer> queue = new LinkedList<>();
        int[] ans = new int[rains.length];
        for (int i = 0; i< rains.length;i++) {
            // 当天不下雨,在队列中记录时间
            if (rains[i] == 0) {
                queue.add(i);
            } else {
                // 当天下雨,且该池子已满,需提前抽空
                if (map.containsKey(rains[i])) {
                    boolean flag = false;
                    for(int j = 0;j < queue.size(); j++){
                        if (queue.get(j) > map.get(rains[i])) {
                            ans[i] = -1;
                            ans[queue.get(j)] = rains[i];
                            map.put(rains[i],i);
                            queue.remove(j);
                            flag = true;
                            break;
                        } else {
                            continue;
                        }
                    }
                    if(!flag) return new int[0];

                } else {
                    // 当天下雨,且池子当前未满
                    ans[i] = -1;
                    map.put(rains[i],i);

                }
            }
        }
        // 剩余的不下雨的日子,都抽1号湖
        if (!queue.isEmpty()) {
            for (Iterator<Integer> iter=queue.iterator();iter.hasNext();) {
                ans[iter.next()] = 1;
            }
        }
        return ans;

    }

你可能感兴趣的:(力扣,算法)