zoukankan      html  css  js  c++  java
  • 490. The Maze

    原题链接:https://leetcode.com/articles/the-maze/
    这道题目是需要冲会员才能使用的,然而我个穷逼现在还是失业状态根本冲不起。。。以后如果把免费题目都刷完了的话,再来冲会员刷这些题目吧!

    我的思路

    迷宫类问题首先想到的就是回溯法了,思考+实现用了近 3 个小时,终于又写出了简单粗暴的实现来了:

    import java.util.Stack;
    
    /**
     * Created by clearbug on 2018/2/26.
     */
    public class Solution {
    
        public static void main(String[] args) {
            Solution s = new Solution();
            /**
             * 0 0 1 0 0
             0 0 0 0 0
             0 0 0 1 0
             1 1 0 1 1
             0 0 0 0 0
             */
            int[][] board = {
                    {0, 0, 1, 0, 0},
                    {0, 0, 0, 0, 0},
                    {0, 0, 0, 1, 0},
                    {1, 1, 0, 1, 1},
                    {0, 0, 0, 0, 0},
            };
            System.out.println(s.traverse(board, 0, 4, 4, 4));
    
            /**
             * 0 0 1 0 0
             0 0 0 0 0
             0 0 0 1 0
             1 1 0 1 1
             0 0 0 0 0
    
             */
            int[][] board2 = {
                    {0, 0, 1, 0, 0},
                    {0, 0, 0, 0, 0},
                    {0, 0, 0, 1, 0},
                    {1, 1, 0, 1, 1},
                    {0, 0, 0, 0, 0},
            };
            System.out.println(s.traverse(board2, 0, 4, 3, 2));
        }
    
        public Stack<String> traverse(int[][] board, int rowStart, int colStart, int rowDest, int colDest) {
            board[rowStart][colStart] = -1; // 标记起始位置已来过
    
            Stack<String> res = new Stack<>();
            boolean dfsRes = dfs(board, rowStart, colStart, rowDest, colDest, res);
            System.out.println(dfsRes);
            return res;
        }
    
        public boolean dfs(int[][] board, int rowStart, int colStart, int rowDest, int colDest, Stack<String> res) {
            if (rowStart == rowDest && colStart == colDest) { // 说明已抵达目的地
                return true;
            }
    
            boolean exist = false;
    
            // up
            int upRow = rowStart - 1;
            while (upRow >= 0 && board[upRow][colStart] < 1) { // board[upRow][colStart] = 0 or board[upRow][colStart] = -1
                exist = true;
                upRow--;
            }
            if (exist) {
                upRow++;
                res.push("up");
                if (upRow == rowDest && colStart == colDest) { // 说明已抵达目的地
                    return true;
                }
                if (board[upRow][colStart] == -1) { // 说明来过这个位置,目前又循环回来了,所以是死路
                    res.pop();
                } else {
                    board[upRow][colStart] = -1; // 标记这个位置已来过
                    if (dfs(board, upRow, colStart, rowDest, colDest, res)) {
                        return true;
                    } else {
                        res.pop();
                    }
                }
            }
    
    
            exist = false;
            // down
            int downRow = rowStart + 1;
            while (downRow < board.length && board[downRow][colStart] < 1) { // board[downRow][colStart] = 0 or board[downRow][colStart] = -1
                exist = true;
                downRow++;
            }
            if (exist) {
                downRow--;
                res.push("down");
                if (downRow == rowDest && colStart == colDest) { // 说明已抵达目的地
                    return true;
                }
                if (board[downRow][colStart] == -1) { // 说明来过这个位置,目前又循环回来了,所以是死路
                    res.pop();
                } else {
                    board[downRow][colStart] = -1; // 标记这个位置已来过
                    if (dfs(board, downRow, colStart, rowDest, colDest, res)) {
                        return true;
                    } else {
                        res.pop();
                    }
                }
            }
    
            exist = false;
            // left
            int leftCol = colStart - 1;
            while (leftCol >= 0 && board[rowStart][leftCol] < 1) {
                exist = true;
                leftCol--;
            }
            if (exist) {
                leftCol++;
                res.push("left");
                if (rowStart == rowDest && leftCol == colDest) {
                    return true;
                }
                if (board[rowStart][leftCol] == -1) {
                    res.pop();
                } else {
                    board[rowStart][leftCol] = -1;
                    if (dfs(board, rowStart, leftCol, rowDest, colDest, res)) {
                        return true;
                    } else {
                        res.pop();
                    }
                }
            }
    
            exist = false;
            // right
            int rightCol = colStart + 1;
            while (rightCol < board[rowStart].length && board[rowStart][rightCol] < 1) {
                exist = true;
                rightCol++;
            }
            if (exist) {
                rightCol--;
                res.push("right");
                if (rowStart == rowDest && rightCol == colDest) {
                    return true;
                }
                if (board[rowStart][rightCol] == -1) {
                    res.pop();
                } else {
                    board[rowStart][rightCol] = -1;
                    if (dfs(board, rowStart, rightCol, rowDest, colDest, res)) {
                        return true;
                    } else {
                        res.pop();
                    }
                }
            }
    
            return false;
        }
    
    
    }
    

    当然了,可以使用类似骑士游历问题中的预测算法来提高效率。下面就来看看官方解答是怎么的吧!

    官方方法一(深入优先搜索)

    深度优先搜索,英文全称为 Depth First Search,简称为 DFS。毫无疑问,跟我的思路是一样的,就是代码更加简洁,所以我的解法其实就是深度优先搜索啦!

    官方解法二(广度优先搜索)

    广度优先搜索,英文全称 Breadth First Search,简称 BFS。不过我思考了下,这种广度优先搜索算法最终是无法求出小球所走过的路径的,只能判断小球最终是否会到达目的地。还是按照惯例抄袭一遍代码就当学会了吧:

    import java.util.LinkedList;
    import java.util.Stack;
    import java.util.Queue;
    
    /**
     * Created by clearbug on 2018/2/26.
     */
    public class Solution {
    
        public static void main(String[] args) {
            Solution s = new Solution();
            /**
             * 0 0 1 0 0
             0 0 0 0 0
             0 0 0 1 0
             1 1 0 1 1
             0 0 0 0 0
             */
            int[][] board = {
                    {0, 0, 1, 0, 0},
                    {0, 0, 0, 0, 0},
                    {0, 0, 0, 1, 0},
                    {1, 1, 0, 1, 1},
                    {0, 0, 0, 0, 0},
            };
            System.out.println(s.hasPath(board, new int[]{0, 4}, new int[]{4, 4}));
    
            /**
             * 0 0 1 0 0
             0 0 0 0 0
             0 0 0 1 0
             1 1 0 1 1
             0 0 0 0 0
    
             */
            int[][] board2 = {
                    {0, 0, 1, 0, 0},
                    {0, 0, 0, 0, 0},
                    {0, 0, 0, 1, 0},
                    {1, 1, 0, 1, 1},
                    {0, 0, 0, 0, 0},
            };
            System.out.println(s.hasPath(board2, new int[]{0, 4}, new int[]{3, 2}));
        }
    
        public boolean hasPath(int[][] maze, int[] start, int[] dest) {
            boolean[][] visited = new boolean[maze.length][maze[0].length];
            visited[start[0]][start[1]] = true;
    
            int[][] dirs = {
                    {0, 1},
                    {0, -1},
                    {-1, 0},
                    {1, 0}
            };
    
            Queue<int[]> queue = new LinkedList<>();
            queue.add(start);
    
            while (!queue.isEmpty()) {
                int[] s = queue.remove();
                if (s[0] == dest[0] && s[1] == dest[1]) {
                    return true;
                }
                for (int[] dir : dirs) {
                    int x = s[0] + dir[0];
                    int y = s[1] + dir[1];
                    while (x >= 0 && y >= 0 && x < maze.length && y < maze[0].length && maze[x][y] == 0) {
                        x += dir[0];
                        y += dir[1];
                    }
                    if (!visited[x - dir[0]][y - dir[1]]) {
                        queue.add(new int[]{x - dir[0], y - dir[1]});
                        visited[x - dir[0]][y - dir[1]] = true;
                    }
                }
            }
    
            return false;
        }
    
    }
    
  • 相关阅读:
    【JavsScript】父子页面之间跨域通信的方法
    【JavaScript】【译】编写高性能JavaScript
    【JavaScript】你知道吗?Web的26项基本概念和技术
    【299】◀▶ IDL
    Python
    Cadence 信号完整性(一)-- 仿真步骤3
    「S-A-L-T-A」项目失败总结!
    java如何遍历hashMap
    Python
    VM网络无法连接--提示ethernet0无法连接到虚拟网络
  • 原文地址:https://www.cnblogs.com/optor/p/8533068.html
Copyright © 2011-2022 走看看