leetcode1293 搜索:BFS总结

 BFS

BFS的典型案例就是走迷宫,每一步不是一直往前走,而是要考虑当前同步内有几个能走的,再从这么多个里面继续往下走。

广度优先搜索一层一层遍历,每一层遍历到的所有新节点,要用队列先存储起来以备下一层遍历的时候再遍历;而深度优先搜索在遍历到一个新节点时立马对新节点进行

遍历:从节点 0 出发开始遍历,得到到新节点 6 时,立马对新节点 6 进行遍历,得到新节点 4;如此反复以这种方式遍历新节点,直到没有新节点了,此时返回。返回到

根节点 0 的情况是,继续对根节点 0 进行遍历,得到新节点 2,然后继续以上步骤。

本题中,玩家在移动时会导致网格结构的变化,但实际上,玩家在最短路径中显然不会经过同一位置超过两次,因此最多消除k个障碍物等价于最多经过k个障碍物。

 核心思想就是把每一个经过的点进行处理标记,如果到了终点马上返回则一定是最短路径。

class Solution {
    private int[][] dir = new int[][] {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

    public int shortestPath(int[][] grid, int k) {
        int m = grid.length;
        int n = grid[0].length;
        boolean[][][] visited = new boolean[m][n][k + 1];
        Queue<Point> queue = new LinkedList<>();

        queue.add(new Point(0, 0, 0));

        // **核心逻辑**:访问记录二维扩展为三维
        visited[0][0][0] = true;

        int distance = 0;
        while (!queue.isEmpty()) {
            distance++;

            int size = queue.size();

            for (int i = 0; i < size; i++) {

                Point point = queue.poll();

                int x = point.x;
                int y = point.y;
                int z = point.z;

                // 找到障碍物
                if (x == m - 1 && y == n - 1) {
                    return distance -1;
                }

                // 4个方向移动
                for (int j = 0; j < 4; j++) {
                    int newX = x + dir[j][0];
                    int newY = y + dir[j][1];
                    int newZ = z;

                    if (newX < 0 || newX >= m || newY < 0 || newY >= n) {
                        continue;
                    }

                    // **核心逻辑**:有障碍物要对其进行处理,计算是否还能消除障碍物
                    if (grid[newX][newY] == 1) {
                        // 没有消除 k 个障碍物,可以继续消除
                        if (z < k) {
                            newZ = z + 1;
                        } else {
                            // 已经消除 k 个障碍物
                            continue;
                        }
                    }

                    if (!visited[newX][newY][newZ]) {
                        queue.add(new Point(newX, newY, newZ));
                        visited[newX][newY][newZ] = true;
                    }
                }
            }
        }
        return -1;
    }

    class Point {
        int x;

        int y;

        int z;

        public Point(int x, int y, int z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }
    }
}
public int minPathLength(int[][] grids, int tr, int tc) {
    int[][] next = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    int m = grids.length, n = grids[0].length;
    Queue<Position> queue = new LinkedList<>();
    queue.add(new Position(0, 0, 1));
    while (!queue.isEmpty()) {
        Position pos = queue.poll();
        for (int i = 0; i < 4; i++) {
            Position nextPos = new Position(pos.r + next[i][0], pos.c + next[i][1], pos.length + 1);
            if (nextPos.r < 0 || nextPos.r >= m || nextPos.c < 0 || nextPos.c >= n) continue;
            if (grids[nextPos.r][nextPos.c] != 1) continue;
            grids[nextPos.r][nextPos.c] = 0;
            if (nextPos.r == tr && nextPos.c == tc) return nextPos.length;
            queue.add(nextPos);
        }
    }
    return -1;
}

private class Position {
    int r, c, length;
    public Position(int r, int c, int length) {
        this.r = r;
        this.c = c;
        this.length = length;
    }
}
原文地址:https://www.cnblogs.com/sjh-dora/p/12904790.html