LeetCode-1488.避免洪水泛滥

这里是题目描述:LeetCode-1488.避免洪水泛滥

思路详解:

  1. 定义如下三个数据结构:
    a. Map<Integer, LinkedList<Integer>>,存储每个湖对应的下雨日期列表,例如 1842=><1,21,31>; 1843=><2,22,32>
    b. PriorityQueue<Lake>,这是一个小堆,存储的是湖泊的下一个雨天,谁最近就会排在最上面
    c. Set<Integer> fullLacks,存储哪些湖泊是满的
  2. 算法步骤如下:
    a. 遍历数组rains,把小雨的日期列表存储到Map<Integer, LinkedList<Integer>> map
    b. 再次遍历数组rains,并做如下判断:
    i. 如果当前是下雨天
    如果当前湖泊已经满了,则返回[],表示无解
    否则,把当前湖泊的下一个雨天加入到小堆priQueue,并且把当前的湖泊设置为已满
    ii. 如果当前不下雨
    如果当前小堆为空(表示目前所有湖泊都是空的),则默认抽湖泊1
    否则,从最小堆堆顶返回并抽最近要下雨的湖泊(贪心原则),移除最小堆proQueue的堆顶,并把当前的湖泊移除自fullLakes

题解代码:

class Solution {
    public int[] avoidFlood(int[] rains) {
        HashSet<Integer> fullLackSet=new HashSet<>(); //当前有水的湖泊
        PriorityQueue<Lack> priQueue=new PriorityQueue<>(); //当前有水的湖泊下一次下雨日期的优先队列
        HashMap<Integer, LinkedList<Integer>> lackRainDay=new HashMap<>(); //每个湖泊的下雨日期列表
        for(int i=0;i<rains.length;i++) //第一次遍历,构建lackRainDay
        {
            if(!lackRainDay.containsKey(rains[i]))
            {
                lackRainDay.put(rains[i],new LinkedList<>());
            }
            lackRainDay.get(rains[i]).add(i);
        }
        int[] res=new int[rains.length];
        for(int i=0;i<rains.length;i++)
        {
            if(rains[i]!=0)
            {
                if(fullLackSet.contains(rains[i])) //发生洪水泛滥
                {
                    return new int[0];
                }
                else //将当前湖泊加入fullLackSet。如果该湖泊有下一次下雨,将该湖泊编号和下一次下雨日期存入priQueue
                {
                    fullLackSet.add(rains[i]);
                    lackRainDay.get(rains[i]).removeFirst();
                    if(!lackRainDay.get(rains[i]).isEmpty())
                    {
                        Lack lack=new Lack(rains[i],lackRainDay.get(rains[i]).getFirst());
                        priQueue.offer(lack);
                    }
                }
                res[i]=-1;
            }
            else //rain[i]==0
            {
                if(!priQueue.isEmpty())
                {
                    Lack lack=priQueue.remove();
                    fullLackSet.remove(lack.id);
                    res[i]=lack.id;
                }
                else
                {
                    res[i]=1;
                }
            }
        }
        return res;
    }
}
class Lack implements java.lang.Comparable<Lack>
{
    int id;
    int nextRainDay;

    public Lack(int id, int nextRainDay) {
        this.id = id;
        this.nextRainDay = nextRainDay;
    }
    public int compareTo(Lack lack)
    {
        return this.nextRainDay-lack.nextRainDay;
    }
}

时间复杂度:O(nlogn)
空间复杂度:O(n)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值