开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第25天,点击查看活动详情
前言
小白算法比较菜,希望能激励我每日更新,从leetcode第一题开始,2022年目标2000分,现在1995!!
力扣第 323 场双周赛-力扣
第 323 场双周赛
参赛的人越来越少了,可算是跌破了5000了
近几次排名对比。
2503. 矩阵查询可获得的最大分数
给你一个大小为 m x n 的整数矩阵 grid 和一个大小为 k 的数组 queries 。
找出一个大小为 k 的数组 answer ,且满足对于每个整数 queres[i] ,你从矩阵 左上角 单元格开始,重复以下过程:
如果 queries[i] 严格 大于你当前所处位置单元格,如果该单元格是第一次访问,则获得 1 分,并且你可以移动到所有 4 个方向(上、下、左、右)上任一 相邻 单元格。
否则,你不能获得任何分,并且结束这一过程。
在过程结束后,answer[i] 是你可以获得的最大分数。注意,对于每个查询,你可以访问同一个单元格 多次 。
返回结果数组 answer 。
示例1:
输入:grid = [[1,2,3],[2,5,7],[3,5,1]], queries = [5,6,2]
输出:[5,8,1]
解释:上图展示了每个查询中访问并获得分数的单元格。
示例2:
输入: 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了