LeetCode-迷宫问题


上篇说到广度优先搜索算法,今天就来做一个应用广度优先算法的力扣算法题吧。这个题是力扣上很常见的求最短路径类型的算法题,对于这种题如果没有解题的算法思路,看到题基本就是脑子一片空白,无从下手的关键。但是使用广度优先搜索算法去求解它时,代码实现却非常简单。

迷宫

题目:给一个二维列表,表示迷宫(0表示通道,1表示围墙)。起点坐标[x=1,y=0];终点坐标[x=9,y=8]。给出算法,求一条走出迷宫的最短路径。其中x表示横坐标,y表示纵坐标。

    private static int[][] maze = {
            {1,1,1,1,1,1,1,1,1,1},
            {0,0,0,1,0,0,0,1,0,1},
            {1,0,0,1,0,0,0,1,0,1},
            {1,0,0,0,0,1,1,0,0,1},
            {1,0,1,1,1,0,0,0,0,1},
            {1,0,0,0,1,0,0,0,0,1},
            {1,0,1,0,0,0,1,0,0,1},
            {1,0,1,1,1,0,1,1,0,1},
            {1,1,0,0,0,0,0,0,0,1},
            {1,1,1,1,1,1,1,1,0,1}
    };

为了更好理解,对应的迷宫的图如下,其中黑色代表墙,白色代表通道。红色是一条最短路径

迷宫

解题思路

解题思路不多说了,使用广度优先搜索算法即可找到最短迷宫路径。

代码实现

Java版本

package com.example.maze;

import java.util.ArrayList;
import java.util.List;

/**
 * @Auther: Lushunjian
 * @Date: 2020/5/28 22:12
 * @Description:
 */
public class MazeTest {

    private static int[][] maze = {
            {1,1,1,1,1,1,1,1,1,1},
            {0,0,0,1,0,0,0,1,0,1},
            {1,0,0,1,0,0,0,1,0,1},
            {1,0,0,0,0,1,1,0,0,1},
            {1,0,1,1,1,0,0,0,0,1},
            {1,0,0,0,1,0,0,0,0,1},
            {1,0,1,0,0,0,1,0,0,1},
            {1,0,1,1,1,0,1,1,0,1},
            {1,1,0,0,0,0,0,0,0,1},
            {1,1,1,1,1,1,1,1,0,1}
    };
    private static Node startNode = new Node(null,0,1,0);
    private static Node endNode = new Node(null,0,9,8);

    // 1:墙   0:路   10*10 = x*y
    /**
     * 上:maze[x-1][y]
     * 下:maze[x+1][y]
     * 左:maze[x][y-1]
     * 右:maze[x][y+1]
     * */
    public static void main(String[] args){
        List<Node> list = new ArrayList<>();
        list.add(startNode);
        Node node = getPath(list);
        while (true){
            System.out.println("x:"+node.getCoX()+"--y:"+node.getCoY());
            node = node.getPreNode();
            if(node == null)
                break;
        }
    }

    private static Node getPath(List<Node> nodeList){
        List<Node> nextNodes = new ArrayList<>();
        for(Node node : nodeList){
            maze[node.getCoX()][node.getCoY()] = 1;
            nextNodes.addAll(getNextNodes(node));
        }
        for(Node node : nextNodes){
            if(node.getCoX() == endNode.getCoY() && node.getCoY() == endNode.getCoY()){
                return node;
            }
        }
        return getPath(nextNodes);
    }

    // 返回节点的下一个可达节点集合
    private static List<Node> getNextNodes(Node node){
        int x = node.getCoX();
        int y = node.getCoY();
        List<Node> nextNodes = new ArrayList<>();
        // 如果向下不越界,且下方不是墙
        if(x<maze.length && maze[x+1][y] ==0)
            nextNodes.add(new Node(node,maze[x+1][y],x+1,y));
        if(y<maze[0].length && maze[x][y+1] == 0)
            nextNodes.add(new Node(node,maze[x][y+1],x,y+1));
        if(x>0 && maze[x-1][y] == 0)
            nextNodes.add(new Node(node,maze[x-1][y],x-1,y));
        if(y>0 && maze[x][y-1]==0)
            nextNodes.add(new Node(node,maze[x][y-1],x,y-1));
        return nextNodes;
    }


    static class Node{
        private Node preNode;
        private int value;
        private int coX;
        private int coY;

        public Node(Node preNode, int value, int coX, int coY) {
            this.preNode = preNode;
            this.value = value;
            this.coX = coX;
            this.coY = coY;
        }

        public Node getPreNode() {
            return preNode;
        }

        public void setPreNode(Node preNode) {
            this.preNode = preNode;
        }

        public int getValue() {
            return value;
        }

        public void setValue(int value) {
            this.value = value;
        }

        public int getCoX() {
            return coX;
        }

        public void setCoX(int coX) {
            this.coX = coX;
        }

        public int getCoY() {
            return coY;
        }

        public void setCoY(int coY) {
            this.coY = coY;
        }
    }
}

Author: 顺坚
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source 顺坚 !
评论
 Previous
对Docker的理解 对Docker的理解
在工作中有接触过docker部署,但只限于简单的使用,对于docker不甚了解,只是大致知道它是一种进程级别的虚拟化技术,因此本文是我对Docker技术的整理和总结。Docker是时下热门的容器技术,相信作为一名开发人员,你也一定听说过或者
2020-05-31
Next 
广度优先搜索算法BFS 广度优先搜索算法BFS
最近在看到力扣上一道推箱子算法题时,思考了很久也想不到解题思路。于是查了一下推箱子的解题思路,便查到了广度优先搜索算法(BFS),广度优先搜索算法专门用于解决最短路径问题,其算法思路也很简单。而推箱子问题就可以用广度搜索算法解决,与它类似的
2020-05-27
  TOC