这道题可以用优先队列(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

这样每个查询都得到了正确答案。

 

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐