题解 | #迷宫问题#

迷宫问题

https://www.nowcoder.com/practice/cf24906056f4488c9ddb132f317e03bc

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner fzhinput = new Scanner(System.in);
        int hang = fzhinput.nextInt();
        int lie = fzhinput.nextInt();
        int mgsz[][] = new int[hang][lie];
        int h = 0, l = 0;
        for (int i = 0; i < hang; i++) {
            for (int j = 0; j < lie; j++) {
                mgsz[i][j] = fzhinput.nextInt();
            }
        }

        List<int[]> path = findPath(mgsz, hang, lie);

        if (path != null) {
            for (int[] coord : path) {
                System.out.println("(" + coord[0] + "," + coord[1] + ")");
            }
        } else {
            System.out.println("No path found");
        }

        fzhinput.close();
    }
    // 定义方向数组,用于表示四个移动方向:上、下、左、右
    static int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    
    // BFS 查找最短路径
    public static List<int[]> findPath(int[][] mgsz, int hang, int lie) {
        // 队列用于存储路径中的点,队列中的每个元素是一个三元组 [x, y, 路径]
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[]{0, 0});  // 起点 (0,0)
        
        // 用于记录访问过的点,防止重复访问
        boolean[][] visited = new boolean[hang][lie];
        visited[0][0] = true;
        
        // 用于记录每个点的前驱节点,以便最终还原路径
        int[][][] predecessor = new int[hang][lie][2];
        for (int i = 0; i < hang; i++) {
            for (int j = 0; j < lie; j++) {
                predecessor[i][j] = new int[]{-1, -1};  // 初始化为 -1,表示没有前驱
            }
        }
        
        while (!queue.isEmpty()) {
            int[] current = queue.poll();
            int x = current[0], y = current[1];
            
            // 如果到达终点,开始构建路径
            if (x == hang - 1 && y == lie - 1) {
                List<int[]> path = new LinkedList<>();
                while (x != -1 && y != -1) {
                    path.add(0, new int[]{x, y});  // 将当前点插入到路径开头
                    int[] pred = predecessor[x][y];  // 获取前驱节点
                    x = pred[0];
                    y = pred[1];
                }
                return path;  // 返回路径
            }
            
            // 尝试四个方向移动
            for (int i=0;i<4;i++) {
                int newX = x + directions[i][0];
                int newY = y + directions[i][1];
                
                // 检查是否在边界内,是否可以走(值为 0),且没有访问过
                if (newX >= 0 && newX < hang && newY >= 0 && newY < lie 
                    && mgsz[newX][newY] == 0 && !visited[newX][newY]) {
                    
                    visited[newX][newY] = true;  // 标记为已访问
                    queue.offer(new int[]{newX, newY});  // 将该点加入队列
                    predecessor[newX][newY] = new int[]{x, y};  // 记录前驱节点
                }
            }
        }
        
        return null;  // 如果找不到路径,返回 null
    }
    
}

全部评论

相关推荐

一名愚蠢的人类:多少games小鬼留下了羡慕的泪水
投递荣耀等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务