【力扣周赛】第 357 场周赛(⭐反悔贪心)

news/2024/5/20 10:13:02 标签: leetcode, 算法, 反悔贪心, 贪心,

文章目录

  • 竞赛链接
  • Q1:6925. 故障键盘
    • 解法1——直接模拟
    • 解法2——双端队列
  • Q2:6953. 判断是否能拆分数组(贪心
  • Q3:2812. 找出最安全路径⭐
    • 解法1——多源BFS+瓶颈路模型?
    • 解法2——多源BFS + 倒序枚举答案 + 并查集(TODO)
  • Q4:2813. 子序列最大优雅度⭐⭐⭐⭐⭐(贪心>反悔贪心
  • 成绩记录

竞赛链接

Q1:6925. 故障键盘

https://leetcode.cn/problems/faulty-keyboard/
在这里插入图片描述

提示:
1 <= s.length <= 100
s 由小写英文字母组成
s[0] != 'i'

解法1——直接模拟

遇到 ‘i’ 翻转已有的字符串,其它字符直接添加即可。

class Solution {
    public String finalString(String s) {
        StringBuilder ans = new StringBuilder();
        for (char ch: s.toCharArray()) {
            if (ch != 'i') ans.append(ch);
            else ans.reverse();
        }
        return ans.toString();
    }
}

解法2——双端队列

用一个变量维护当前翻转了几次,来决定新来的字符添加在开头还是结尾。

class Solution {
    public String finalString(String s) {
        int f = 0;
        Deque<Character> dq = new ArrayDeque<>();
        for (char ch: s.toCharArray()) {
            if (ch == 'i') f++;
            else {
                if (f % 2 == 0) dq.offerLast(ch);
                else dq.offerFirst(ch);
            }
        }
        StringBuilder ans = new StringBuilder();
        for (char ch: dq) ans.append(ch);
        if (f % 2 == 1) ans.reverse();
        return ans.toString();
    }
}

Q2:6953. 判断是否能拆分数组(贪心

https://leetcode.cn/problems/check-if-it-is-possible-to-split-array/

在这里插入图片描述

提示:
1 <= n == nums.length <= 100
1 <= nums[i] <= 100
1 <= m <= 200

在这里插入图片描述

class Solution {
    public boolean canSplitArray(List<Integer> nums, int m) {
        int n = nums.size();
        if (n == 1 || n == 2) return true;
        for (int i = 0; i < n - 1; ++i) {
            if (nums.get(i) + nums.get(i + 1) >= m) return true;
        }
        return false;
    }
}

Q3:2812. 找出最安全路径⭐

https://leetcode.cn/problems/find-the-safest-path-in-a-grid/

在这里插入图片描述

提示:
1 <= grid.length == n <= 400
grid[i].length == n
grid[i][j] 为 0 或 1
grid 至少存在一个小偷

解法1——多源BFS+瓶颈路模型?

第一遍 bfs 求出各个位置的安全系数。
第二遍 bfs,将各个位置的安全系数更新为从终点开始的路径上的较小值。

class Solution {
    int[] dx = new int[]{-1, 0, 1, 0}, dy = new int[]{0, -1, 0, 1};
    
    public int maximumSafenessFactor(List<List<Integer>> grid) {
        int n = grid.size();
        if (grid.get(0).get(0) == 1 || grid.get(n - 1).get(n - 1) == 1) return 0;
        
        int[][] g = new int[n][n], safe = new int[n][n];
        Queue<int[]> q = new LinkedList<>();

        // 第一遍多源bfs 求出各个位置的安全系数
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid.get(i).get(j) == 1) {
                    g[i][j] = 1;
                    q.offer(new int[]{i, j});
                }
            }
        }
        while (!q.isEmpty()) {
            int sz = q.size();
            for (int i = 0; i < sz; ++i) {
                int[] cur = q.poll();
                int x = cur[0], y = cur[1];
                for (int k = 0; k < 4; ++k) {
                    int nx = x + dx[k], ny = y + dy[k];
                    if (nx >= 0 && ny >= 0 && nx < n && ny < n && g[nx][ny] == 0) {
                        q.offer(new int[]{nx, ny});
                        g[nx][ny] = g[x][y] + 1;
                    }
                }
            }
        }
        
        // 第二遍bfs 从终点出发,求出各个路径的最小安全系数
        q.offer(new int[]{n - 1, n - 1});
        safe[n - 1][n - 1] = g[n - 1][n - 1];
        while (!q.isEmpty()) {
            int[] cur = q.poll();
            int x = cur[0], y = cur[1];
            for (int k = 0; k < 4; ++k) {
                int nx = x + dx[k], ny = y + dy[k];
                if (nx >= 0 && ny >= 0 && nx < n && ny < n) {
                    int nsafe = Math.min(g[nx][ny], safe[x][y]);
                    if (nsafe > safe[nx][ny]) {
                        safe[nx][ny] = nsafe;
                        q.offer(new int[]{nx, ny});
                    }
                }
            }
        }

        return safe[0][0] - 1;
    }
}

解法2——多源BFS + 倒序枚举答案 + 并查集(TODO)

https://leetcode.cn/problems/find-the-safest-path-in-a-grid/solutions/2375565/jie-jin-on2-de-zuo-fa-duo-yuan-bfsdao-xu-r5um/

在这里插入代码片

Q4:2813. 子序列最大优雅度⭐⭐⭐⭐⭐(贪心>反悔贪心

https://leetcode.cn/problems/maximum-elegance-of-a-k-length-subsequence/

在这里插入图片描述

提示:
1 <= items.length == n <= 10^5
items[i].length == 2
items[i][0] == profiti
items[i][1] == categoryi
1 <= profiti <= 10^9
1 <= categoryi <= n
1 <= k <= n

思路——贪心>反悔贪心

https://leetcode.cn/problems/maximum-elegance-of-a-k-length-subsequence/solutions/2375128/fan-hui-tan-xin-pythonjavacgo-by-endless-v2w1/
在这里插入图片描述

代码

核心的思想是:x + y^2,枚举 y^2的值,并使得 x 在该枚举值下的值最大,就得到了该枚举值下的最大值。比较得到的所有的最大值就是最终结果了。

class Solution {
    public long findMaximumElegance(int[][] items, int k) {
        // 把利润从大到小排序
        Arrays.sort(items, (a, b) -> b[0] - a[0]);
        long ans = 0, totalProfit = 0;
        Set<Integer> vis = new HashSet<>();
        Deque<Integer> duplicate = new ArrayDeque<>();
        for (int i = 0; i < items.length; ++i) {
            int profit = items[i][0], category = items[i][1];
            if (i < k) {
                totalProfit += profit;
                if (!vis.add(category)) {
                    // 如果已经有这个类别了,就把当前的放在栈顶
                    duplicate.push(profit);
                }
            } else if (!duplicate.isEmpty() && vis.add(category)) {
                // 如果当前栈不为空,且当前种类没有出现过
                totalProfit += profit - duplicate.pop();    // 修改利润
            }

            ans = Math.max(ans, totalProfit + (long) vis.size() * vis.size());
        }
        return ans;
    }
}

相似题目列表

做完之后感觉这两个题目更相似一些,但是和贪心>反悔贪心关系不是那么大。

LCP 30. 魔塔游戏(+贪心

https://leetcode.cn/problems/p0NxJO/description/

在这里插入图片描述
提示:
1 <= nums.length <= 10^5
-10^5 <= nums[i] <= 10^5

先检查是否有答案存在。

如果有答案存在,就将已经枚举到的负值放入中,每次 s <= 0 时,就取出最小的那个负数移动到末尾即可。

class Solution {
    public int magicTower(int[] nums) {
        if (Arrays.stream(nums).sum() < 0) return -1;
        int ans = 0;
        // pq中存放目前遇到的负数
        PriorityQueue<Integer> pq = new PriorityQueue<>();
        long s = 1;
        for (int x: nums) {
            s += x;
            if (x < 0) pq.offer(x);
            while (s <= 0) {
                // 每次把最小的移动到最后面去
                s -= pq.poll();
                ans++;
            }
        }
        return ans;
    }
}

871. 最低加油次数(+贪心

https://leetcode.cn/problems/minimum-number-of-refueling-stops/

在这里插入图片描述

提示:
1 <= target, startFuel <= 10^9
0 <= stations.length <= 500
1 <= positioni < positioni+1 < target
1 <= fueli < 10^9

维护目前可以加的油,但是先不加,等到走不动了再一个个加。

class Solution {
    public int minRefuelStops(int target, int startFuel, int[][] stations) {
        if (startFuel >= target) return 0;

        Arrays.sort(stations, (x, y) -> x[0] - y[0]);   // 按照位置排序
        PriorityQueue<Integer> pq = new PriorityQueue<Integer>((x, y) -> y - x);
        int p = startFuel, ans = 0;
        for (int i = 0; i < stations.length; ++i) {
            while (p < stations[i][0] && !pq.isEmpty()) {
                p += pq.poll();
                ans++;
            }
            if (p < stations[i][0]) break;
            if (p >= target) return ans;
            pq.offer(stations[i][1]);
        }
        while (p < target && !pq.isEmpty()) {
            p += pq.poll();
            ans++;
        }
        return p < target? -1: ans;
    }
}

成绩记录

在这里插入图片描述

T3 借助了一些些外力。

在这里插入图片描述
上小分。


http://www.niftyadmin.cn/n/5003379.html

相关文章

Redis基础知识(三):缓存穿透、缓存击穿、缓存雪崩

文章目录 一、缓存穿透出现过程解决方法 二、缓存击穿出现过程解决方法 三、缓存雪崩出现过程解决方法 我们在项目中大量使用Redis承接海量数据的冲击&#xff0c;但是使用过程中也会遇到一些特殊的情况&#xff0c;这个就是缓存击穿、缓存穿透、缓存雪崩。 一、缓存穿透 缓存…

linux下打包qt程序

项目场景&#xff1a; Qt 提供了一个打包工具&#xff0c;叫做 deployqt&#xff0c;可以将应用程序所依赖的库文件都提取出来&#xff0c;并且支持跨平台。在 Windows 系统叫 windeployqt&#xff0c;在 Linux 系统叫 linuxdeployqt&#xff0c;在 Mac 下叫 macdeployqt。但是…

华为云云服务器评测|云耀云服务器实例基础使用实践

&#x1f996;我是Sam9029&#xff0c;一个前端 Sam9029的CSDN博客主页:Sam9029的博客_CSDN博客-JS学习,CSS学习,Vue-2领域博主 **&#x1f431;‍&#x1f409;&#x1f431;‍&#x1f409;恭喜你&#xff0c;若此文你认为写的不错&#xff0c;不要吝啬你的赞扬&#xff0c;求…

20.(地图工具篇)QGIS修改shape字符集UTF-8编码

1&#xff1a;加载shape数据 拉进QGIS编辑区即可。 2&#xff1a;修改字符集 2.1右击Layers中的ground图层&#xff0c;选择properties 2.1修改data source encoding为UTF-8 3&#xff1a;导出新shape文件 3.1 导出入口 3.2 导出文件配置

[数据集][目标检测]裸土识别裸土未覆盖目标检测数据集VOC格式857张2类别

数据集格式&#xff1a;Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件&#xff0c;仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数)&#xff1a;857 标注数量(xml文件个数)&#xff1a;857 标注类别数&#xff1a;2 标注类别名称:["luotu","n…

【SQL学习笔记】关系模型与查询和更新数据

一、关系模型 1.1 主键 主键是关系表中记录的唯一标识。主键的选取非常重要&#xff1a;主键不要带有业务含义&#xff0c;而应该使用BIGINT自增或者GUID类型。主键也不应该允许NULL。 可以使用多个列作为联合主键&#xff0c;但联合主键并不常用。 1.2 外键 FOREIGN KEY …

【C++】函数重载 ② ( 重载函数调用分析 | 函数重载特点 | 函数重载与默认参数 )

文章目录 一、函数重载1、重载函数调用分析2、函数重载特点 二、函数重载与默认参数1、函数重载与默认参数出现的二义性分析2、代码示例 - 定义上述两个函数3、代码示例 - 没有二义性的函数调用4、代码示例 - 出现二义性编译失败 博客总结 : 重载函数 : 使用 相同 的 函数名 ,…

CSP 202303-1 田地丈量

样例输入 4 10 10 0 0 5 5 5 -2 15 3 8 8 15 15 -2 10 3 15 样例输出 44 答题 首先写一个计算面积的函数&#xff0c;既然大小固定就省去了比较&#xff0c;然后是将在范围之外的矩阵给忽略掉&#xff0c;接下来将碰到的矩阵大小缩小为范围之内的&#xff0c;累加即可 #in…