2023/10/13

146 阅读2分钟

1488. 避免洪水泛滥

算法掌握:

  • hash表
  • 链表
  • 迭代器
  • 模拟

解题思路:

本题是一个中等题对语法的熟练度比较高,难度就是一个脑筋急转弯的思维模拟题,下雨天的下标直接赋值 -1 即可,先将没有下雨的情况可以抽水的情况用链表存储起来,因为是顺序存储所有一定是升序,然后如果是下雨天,判断此池子是否已经被填充过了,如果填充过在之前那天开始到至今有没有可以抽取的机会,就与开始存储的链表进行比较即可,有就用掉抽取的机会,并刷新填充池子的时间,抽取机会从链表中删除,(为什么用链表而不是数组是因为,删除数组中一个值,要重新维护数组位置,效率比较慢),不能抽取则直接返回空数组即可

java code:

class Solution {
    public int[] avoidFlood(int[] rains) {
        int size = rains.length;
        int[] ans = new int[size];
        // 默认填充 1
        Arrays.fill(ans, 1);
        // 记录可以抽水的日期
        List<Integer> pump = new LinkedList<>();
        // 记录填充的日期
        Map<Integer, Integer> rainsFill = new HashMap<>();
        for(int i = 0; i < size; i++){
            if(rains[i] == 0) pump.add(i);
            else{
                ans[i] = -1;
                // 如何已经被填过了,判断是否可以抽取
                if (rainsFill.containsKey(rains[i])) {
                    int start = rainsFill.get(rains[i]);
                    boolean isPump = false;
                    for (int j = 0; j < pump.size(); j++) {
                        if (pump.get(j) > start) {
                            ans[pump.get(j)] = rains[i];
                            pump.remove(j);
                            isPump = true;
                            break;
                        }
                    }
                    if (!isPump) return new int[0];
                }
                rainsFill.put(rains[i], i);
            }
        }
        return ans;
    }
}

c++ code:

class Solution {
public:
    vector<int> avoidFlood(vector<int>& rains) {
        int size = rains.size();
        vector<int> ans(size, 1);
        list<int> pump;   // 记录可以抽水的日期
        unordered_map<int, int> rains_fill;  // 记录已被填满的池子所对应填满的日期
        for(int i = 0; i < size; i++){
            if(rains[i] == 0) pump.push_back(i);
            else{
                ans[i] = -1;
                // 已经被填满了,判断是否在前几天可以抽取
                if(rains_fill.find(rains[i]) != rains_fill.end()){
                    int start = rains_fill[rains[i]];
                    // 记录是否能被抽空,初始化不能
                    bool is_pump = false;
                    // 链表通过迭代器遍历
                    for(list<int>::iterator it = pump.begin(); it != pump.end(); it++){
                        if(*it > start){
                            ans[*it] = rains[i];
                            pump.erase(it);
                            is_pump = true;
                            break;
                        }
                    }
                    if(!is_pump) return {};
                }
                // 刷新填满时间
                rains_fill[rains[i]] = i;
            }
        }
        
        return ans;
    }
};