【Zilliz专场】力扣第 271 场周赛复盘

简介: 【Zilliz专场】力扣第 271 场周赛复盘

一、5952. 环和杆

1、题目简介

2、题目解析

  • 签到题,我们使用 Map> 来进行存储
  • 遍历 map,判断 valuesize 是否为 3 就可

3、题目代码

class Solution {
    public int countPoints(String rings) {
        Map<Character, Set<Character>> map = new HashMap<>();
        for (int i = 0; i < rings.length(); i = i + 2) {
            char ch = rings.charAt(i);
            char index = rings.charAt(i + 1);
            if (map.containsKey(index)) {
                map.get(index).add(ch);
            } else {
                Set<Character> set = new HashSet<>();
                set.add(ch);
                map.put(index, set);
            }
        }
        int num = 0;
        for (Set<Character> set : map.values()) {
            if (set.size() == 3) {
                num++;
            }
        }
        return num;
    }
}

二、5953. 子数组范围和

1、题目简介

2、题目解析

  • 这个题,W了三次才过,原因在于:我一开始使用 List> 来进行存储,导致内存直接爆了,时间也超时了
  • 后续想了想优化空间:使用两个最优队列来存储当前的最大值和最小值,这样我们就可以用 O(1) 的时间复杂度获取当前 max - min 的值
  • 最后第4次才过,呜呜呜
  • 第二种做法:我们暴力的同时使用 maxmin 维护当前的最大值和最小值,见 代码二

3、题目代码

代码一 时间复杂度相对 代码二 来说,主要增加了 最优队列选举最大或最小 的时间

3.1 代码一

class Solution {
    public long subArrayRanges(int[] nums) {
        long sum = 0;
        for (int i = 0; i < nums.length; i++) {
            sum = sum + f(nums, i, 0);
        }
        return sum;
    }
    public long f(int[] nums, int index, long sum) {
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
        PriorityQueue<Integer> priorityQueue2 = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        });
        List<Long> path = new ArrayList<>();
        for (int i = index; i < nums.length; i++) {
            priorityQueue.add(nums[i]);
            priorityQueue2.add(nums[i]);
            sum = sum + (priorityQueue.peek() - priorityQueue2.peek());
        }
        return sum;
    }
}

3.2 代码二

class Solution {
    public long subArrayRanges(int[] nums) {
        long sum = 0;
        for (int i = 0; i < nums.length; i++) {
            int max = nums[i];
            int min = nums[i];
            for(int j = i + 1; j < nums.length; j++){
                max = Math.max(max, nums[j]);
                min = Math.min(min, nums[j]);
                sum += max - min;
            }
        }
        return sum;
    }
}

三、5954. 给植物浇水 II

1、题目简介

2、题目解析

  • 模拟题,模拟每次倒水的流程
  • 题主这里W一次是因为忘记 当前的水 = 可浇水 ,忘记相等也可以直接浇水了,笔误。。。。

3、题目代码

class Solution {
    public int minimumRefill(int[] plants, int capacityA, int capacityB) {
        int sum = 0;
        int capacityAMAX = capacityA;
        int capacityBMAX = capacityB;
        // A从开头浇水
        // B从结尾浇水
        int indexA = 0;
        int indexB = plants.length - 1;
        while (indexA < indexB) {
            // A 浇水
            if (plants[indexA] <= capacityA) {
                capacityA = capacityA - plants[indexA];
            } else {
                sum++;
                capacityA = capacityAMAX;
                capacityA = capacityA - plants[indexA];
            }
            // B浇水
            if (plants[indexB] <= capacityB) {
                capacityB = capacityB - plants[indexB];
            } else {
                sum++;
                capacityB = capacityBMAX;
                capacityB = capacityB - plants[indexB];
            }
            indexA++;
            indexB--;
        }
        if (indexA == indexB) {
            if (capacityA >= capacityB) {
                if (plants[indexA] <= capacityA) {
                    capacityA = capacityA - plants[indexA];
                } else {
                    sum++;
                    capacityA = capacityAMAX;
                    capacityA = capacityA - plants[indexA];
                }
            } else {
                // B浇水
                if (plants[indexB] <= capacityB) {
                    capacityB = capacityB - plants[indexB];
                } else {
                    sum++;
                    capacityB = capacityBMAX;
                    capacityB = capacityB - plants[indexB];
                }
            }
        }
        return sum;
    }
}

四、5955. 摘水果

1、题目简介

2、题目解析

  • 题主一开始直接写了一个 dfs 交上去了,不出所料,就这数据量,卡的死死的
  • 我们将题目简化为:在一段区间中,找到最大的水果总数[L,R]
  • 这个区间的范围:我们的总步数为k
  • 我们可以先往右走 i 步,再往左走 k - i,那么我们的区间为:[startPos + i - k + i ,startPos + i]
  • 我们也可以先往左走 i 步,再往左走 k - i,那么我们的区间为:[startPos - i, startPos - i + k - i]
  • 我们可以用前缀和求出整个表上的水果数目,然后暴力求每个区间的获得水果的最大值

3、题目代码

3.1 DFS

public int maxTotalFruits(int[][] fruits, int startPos, int k) {
        Map<Integer, Integer> map = new HashMap<>();
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < fruits.length; i++) {
            int index = fruits[i][0];
            if (max <= index) {
                max = index;
            }
            int value = fruits[i][1];
            map.put(index, value);
        }
        return dfs(map, startPos, k, max, 0);
    }
    public int dfs(Map<Integer, Integer> map, int startPos, int k, int len, int sum) {
        // 判断越界
        if (startPos < 0 || startPos >= len || k == 0) {
            return sum;
        }
        int value = map.getOrDefault(startPos, 0);
        // 判断一下有没有吃到水果
        if (map.containsKey(startPos)) {
            sum = sum + map.get(startPos);
            // 需要将此后设置为0
            map.put(startPos, 0);
        }
        // 然后去下一个状态
        int num1 = dfs(map, startPos - 1, k - 1, len, sum);
        int num2 = dfs(map, startPos + 1, k - 1, len, sum);
        // 最后别忘记了回溯
        map.put(startPos, value);
        return Math.max(num1, num2);
    }

3.2 贪心

class Solution {
    public int maxTotalFruits(int[][] fruits, int startPos, int k) {
        int MAX = 200001;
        int[] arr = new int[MAX];
        int index = 0;
        int currSum = 0;
        for(int i = 0; i < MAX; i++){
            if(index < fruits.length && fruits[index][0] == i){
                currSum = currSum + fruits[index][1];
                index++;
            }
            arr[i] = currSum;
        }
        // 计算K步最多能走的步数
        int res = 0;
        //先往左走i步, 再往右走 k - i 步
        for(int i = 0; i <= k; i++){
            // 防止越界
            int left = Math.max(0, startPos - i);
            int right = Math.min(MAX - 1, left + k - i);
            int curr = arr[right] - (left == 0 ? 0 : arr[left - 1]);
            res = Math.max(res, curr);
        }
        // 先往右走i步,再往左走k - i步
        for(int i = 0; i <= k; i++){
            int right = Math.min(startPos + i, MAX - 1);
            int left = Math.max(0, right - k + i);
            int curr = arr[right] - (left == 0 ? 0 : arr[left - 1]);
            res = Math.max(res, curr);
        }
        return res;
    }
}

五、总结

本周又是三题,由于一些细心问题,导致罚时过多,过三题排名 626 ~ 2250

可以看出,程序员的算法能力逐渐开始上升

下周争取不迟到,争取AK!


相关文章
|
4月前
|
Go
golang力扣leetcode 第 291 场周赛
golang力扣leetcode 第 291 场周赛
38 0
|
4月前
|
Go
golang力扣leetcode第 294 场周赛
golang力扣leetcode第 294 场周赛
32 0
|
4月前
|
算法 Java Go
golang力扣leetcode 第 293 场周赛
golang力扣leetcode 第 293 场周赛
59 0
|
4月前
|
Go
golang力扣leetcode 第 292 场周赛
golang力扣leetcode 第 292 场周赛
38 0
|
6天前
|
存储
Leetcode第382场周赛
```markdown 给定字符串`s`,计算按键变更次数,即使用不同键的次数,不考虑大小写差异。例如,`&quot;aAbBcC&quot;`变更了2次。函数`countKeyChanges`实现此功能。另外,求满足特定模式子集最大元素数,`maximumLength`函数使用`TreeMap`统计次数,枚举并构建子集,返回最大长度。最后,Alice和Bob玩鲜花游戏,Alice要赢需满足鲜花总数奇数、顺时针在[1,n]、逆时针在[1,m],返回满足条件的(x, y)对数,可通过奇偶性分类讨论求解。 ```
11 1
|
6天前
|
存储
Leetcode第383场周赛
在LeetCode第383场周赛中,选手完成了3道题目。第一题是关于边界上的蚂蚁,蚂蚁根据非零整数数组nums的值移动,返回蚂蚁返回边界上的次数。解题方法是计算数组累加和为0的次数。第二题涉及计算网格的区域平均强度,给定一个灰度图像和阈值,返回每个像素所属区域的平均强度。解题关键在于理解相邻像素和区域定义,并计算平均强度。第三题是恢复单词初始状态的最短时间问题,通过移除前k个字符并添加k个字符,求恢复原词所需的最短时间。解题策略是检查去除前k个字符后的子串是否能作为原词的前缀。
11 1
Leetcode第383场周赛
|
4月前
|
Go
golang力扣leetcode 第 295 场周赛
golang力扣leetcode 第 295 场周赛
37 0
|
3天前
|
算法 C++
【刷题】Leetcode 1609.奇偶树
这道题是我目前做过最难的题,虽然没有一遍做出来,但是参考大佬的代码,慢慢啃的感觉的真的很好。刷题继续!!!!!!
6 0
|
3天前
|
算法 索引
【刷题】滑动窗口精通 — Leetcode 30. 串联所有单词的子串 | Leetcode 76. 最小覆盖子串
经过这两道题目的书写,相信大家一定深刻认识到了滑动窗口的使用方法!!! 下面请大家继续刷题吧!!!
8 0

热门文章

最新文章