DeepSeek LeetCode 2503.矩阵查询可获得的最大分数 public int[] maxPoints(int[][] grid, int[] queries)
这道题可以用优先队列(BFS)+ 排序 + 离线查询的思路解决。
核心思路
· 对于每个查询 q,我们需要找出所有值小于 q 的单元格,并统计从 (0,0) 出发能到达多少个。
· 因为查询可能有重复、顺序无关,可以将 queries 排序,从小到大处理,这样就能利用之前的结果。
· 用一个最小堆来按网格值从小到大的顺序扩展可达区域。
算法步骤
1. 将 queries 转成带索引的数组,按值排序。
2. 用最小堆 (grid[r][c], r, c) 存储当前边界,初始放入 (grid[0][0], 0, 0)。
3. 用一个 visited 布尔数组记录是否已访问。
4. 对排序后的每个查询值 (q, idx):
· 从堆中弹出所有值 < q 的格子,每弹出一个计数 +1,并向四个方向扩展(如果邻格未访问且其值也小于 q,直接扩展;否则其值大于等于 q,则不能立刻加入堆作为扩展?这里要注意逻辑)
· 更准确地说:堆里存放的是当前已知可访问区域的边界。弹出时只弹出值 < q 的边界点,然后把它的四个邻居加入堆(无论值多少,因为将来 q 变大时可能被访问),但邻居如果值 < q 要继续处理吗?需要循环直到堆顶值 ≥ q。
详细BFS过程
· 堆里存放元素 (val, r, c)。
· 对每个查询 q:
1. 只要堆非空且堆顶的 val < q:
· 弹出 (val, r, c),count++
· 对四个方向 (nr, nc):
· 未越界且未访问
· 标记访问
· 入堆 (grid[nr][nc], nr, nc)
2. 记录该查询答案为 count
这样,所有查询处理完后,即可得到结果。
时间复杂度
· 每个格子最多入堆一次:O(mn log(mn))
· 查询排序:O(k log k)
· 总复杂度:O(mn log(mn) + k log k)
代码实现
```java
public int[] maxPoints(int[][] grid, int[] queries) {
int m = grid.length, n = grid[0].length;
int k = queries.length;
int[][] qs = new int[k][2];
for (int i = 0; i < k; i++) {
qs[i][0] = queries[i];
qs[i][1] = i;
}
Arrays.sort(qs, (a, b) -> a[0] - b[0]);
// 最小堆: (grid[r][c], r, c)
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]);
boolean[][] visited = new boolean[m][n];
visited[0][0] = true;
pq.offer(new int[]{grid[0][0], 0, 0});
int[] res = new int[k];
int count = 0;
int[][] dirs = {{1,0},{-1,0},{0,1},{0,-1}};
for (int[] q : qs) {
int val = q[0], idx = q[1];
while (!pq.isEmpty() && pq.peek()[0] < val) {
int[] cur = pq.poll();
count++;
int r = cur[1], c = cur[2];
for (int[] d : dirs) {
int nr = r + d[0];
int nc = c + d[1];
if (nr >= 0 && nr < m && nc >= 0 && nc < n && !visited[nr][nc]) {
visited[nr][nc] = true;
pq.offer(new int[]{grid[nr][nc], nr, nc});
}
}
}
res[idx] = count;
}
return res;
}
```
示例验证
以 grid = [[1,2,3],[2,5,7],[3,5,1]], queries = [5,6,1] 为例:
· 排序后 queries: [1,5,6]
· 对 q=1: 只能访问 (0,0) 值为1 → count=1
· 对 q=5: 堆顶 2<5,访问 (0,1) 值为2 → count=2;堆顶 3<5,访问 (0,2) 值为3 → count=3;堆顶 3<5,访问 (1,0) 值为2 → count=4;堆顶 5≥5 停止 → 答案 count=4
· 对 q=6: 继续扩展,最终 count=7
这样每个查询都得到了正确答案。
更多推荐




所有评论(0)