[杨小白]_leetcode_力扣_第 323 场周赛-第四题

77 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第25天,点击查看活动详情

前言

小白算法比较菜,希望能激励我每日更新,从leetcode第一题开始,2022年目标2000分,现在1995!!

力扣第 323 场双周赛-力扣

第 323 场双周赛

参赛的人越来越少了,可算是跌破了5000了

近几次排名对比。

image.png

image.png

image.png

image.png

image.png

2503. 矩阵查询可获得的最大分数

给你一个大小为 m x n 的整数矩阵 grid 和一个大小为 k 的数组 queries 。

找出一个大小为 k 的数组 answer ,且满足对于每个整数 queres[i] ,你从矩阵 左上角 单元格开始,重复以下过程:

如果 queries[i] 严格 大于你当前所处位置单元格,如果该单元格是第一次访问,则获得 1 分,并且你可以移动到所有 4 个方向(上、下、左、右)上任一 相邻 单元格。

否则,你不能获得任何分,并且结束这一过程。

在过程结束后,answer[i] 是你可以获得的最大分数。注意,对于每个查询,你可以访问同一个单元格 多次 。

返回结果数组 answer 。

示例1:

image.png

输入:grid = [[1,2,3],[2,5,7],[3,5,1]], queries = [5,6,2]

输出:[5,8,1]

解释:上图展示了每个查询中访问并获得分数的单元格。

示例2:

image.png

输入: grid = [[5,2,1],[1,1,2]], queries = [3]

输出: [0]

解释: 无法获得分数,因为左上角单元格的值大于等于 3 。

提示:

  • m == grid.length

  • n == grid[i].length

  • 2 <= m, n <= 1000

  • 4 <= m * n <= 105

  • k == queries.length

  • 1 <= k <= 104

  • 1 <= grid[i][j], queries[i] <= 106

代码

我能做出来的第四题确实不多。本题做法:BFS+前缀和

bfs更新后,vis[i][j]表示从0,0能走到i,j需要的queries最小为vis[i][j]

将vis的所有数据填入dp中,并求前缀和。

对于queries[i] = querie来说,他能走到的路就是dp[0]到dp[querie]的和,就是sum[querie]

class Solution {
    public int[] maxPoints(int[][] grid, int[] queries) {
        int[] dp = new int[1000010];
        int[][] vis = new int[grid.length][grid[0].length];
        ArrayList<int[]> arrayList = new ArrayList<>();
        arrayList.add(new int[]{0,0,-1});
        bfs(grid, vis, arrayList);
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[0].length; j++) {
                dp[vis[i][j]] = dp[vis[i][j]] + 1;
            }
        }
        int[] sum = new int[dp.length + 1];
        for (int i = 0; i < dp.length; i++) {
            sum[i + 1] = sum[i] + dp[i];
        }
        for (int i = 0; i < queries.length; i++) {
            queries[i] = sum[queries[i]];
        }
        return queries;
    }
    private void bfs(int[][] grid, int[][] vis,ArrayList<int[]> arr) {
        while (!arr.isEmpty()) {
            ArrayList<int[]> arrayList = new ArrayList<>();
            for (int k = 0; k < arr.size(); k++) {
                int[] ints = arr.get(k);
                int i = ints[0];
                int j = ints[1];
                int max = ints[2];
                if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length) {
                    continue;
                }
                max = Math.max(grid[i][j],max);
                if (vis[i][j] != 0 && vis[i][j] <= max) {
                    continue;
                }
                vis[i][j] = max;
                arrayList.add(new int[]{ i + 1, j,max});
                arrayList.add(new int[]{ i, j + 1,max});
                arrayList.add(new int[]{ i - 1, j,max});
                arrayList.add(new int[]{ i, j - 1,max});
            }
            arr = arrayList;
        }
    }
    private void dfs(int[][] grid, int i, int j, int max, int[][] vis) {
        if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length) {
            return;
        }
        max = Math.max(max, grid[i][j]);
        if (vis[i][j] != 0 && vis[i][j] <= max) {
            return;
        }
        vis[i][j] = max;
        dfs(grid, i + 1, j, max, vis);
        dfs(grid, i, j + 1, max, vis);
        dfs(grid, i - 1, j, max, vis);
        dfs(grid, i, j - 1, max, vis);
    }
}

3.结束

应该是第三次ak了,最近两个月都没有花很多时间在算法上,确实也没什么明显的进步,但是偶尔自己能想出来第四题的感觉还算不错的。

小上一波分,1916到1995了

image.png