Java 实现最优路径查找算法(伪Leetcode路径查找算法)

来源:互联网 发布:属下知罪by枯目剧透 编辑:程序博客网 时间:2024/05/29 11:06

Java 实现最优路径查找算法(伪Leetcode路径查找算法)

今天忙里偷闲写了下关于Leetcode里面的路径查找相关算法,题目在下面的链接,这个题目和它前面的62题是连在一起的,但是这个题目有一个规定是,只能向右和向下查找,这里就有很大的可操作性了,本文是基于四个方向都可以移动来实现的,并且没有规定死开始位置和目标位置。
这里说明一下,这个算法的主要采用的是递归的实现,但是放到Leetcode里面时间复杂度是过不了的,如果有更好的实现思路请私信或者留言给我,算法中有可以改进的地方,也请留言告知,谢谢!
这里发一下题目的链接:
https://leetcode.com/problems/unique-paths-ii/

PS:这个算法不是完全按照leetcode里面的题目,Leetcode里面是规定是只能向右和向下,本文算法实现是没有做规定的.

实现方法:

动态规划算法

实现说明:

  • 动态规划算法实现 两个条件:1、递归方案,2、边界条件
    递归方案:位置点的遍历;
    边界条件:最终目的点和当前遍历的路径深度是否大于查找到的路径的深度;下一个位置点是否是障碍物点或者是否已经同遍历层级遍历过。

  • 该算法是找出所有的路径,在这些路径中可以找到最优解,并且最优解有可能不止一个。

  • 在有第一条路径的时候,获取路径的长度。 然后在递归是可以判断当前路径的长度,如果已经大于已经有结果的最小路径,则直接回退即可,不需要遍历。

实现代码

代码里面是有相应的注释,就不过多解释了

public class Solution {    // 结果容器    private ArrayList<ArrayList<Point>> resultList = new ArrayList<ArrayList<Point>>();    // 已经有路径的步数大小,如果大于这个步数就不用在递归了,肯定不是最优解    private int alreadyPath = -1;    public int uniquePathsWithObstacles(int[][] obstacleGrid) {        return uniquePathsWithObstacles(obstacleGrid, 0, 0,                obstacleGrid.length - 1, obstacleGrid[0].length - 1);    }    private int uniquePathsWithObstacles(int[][] obstacleGrid, int startX,            int startY, int endX, int endY) {        Point[] pointArray = constructPointArray(obstacleGrid);        if (pointArray != null && pointArray.length == 1                && pointArray[0].value == 0) {            return 1;        }        if (pointArray[startY + startX * obstacleGrid[0].length].value == 1                || pointArray[endY + endX * obstacleGrid[0].length].value == 1) {            return 0;        }        ArrayList<Point> list = new ArrayList<Point>();        list.add(pointArray[startY + startX * obstacleGrid[0].length]);        pointArray[startY + startX * obstacleGrid[0].length].IsCheck = true;        caclPath(pointArray, pointArray[startY + startX                * obstacleGrid[0].length], pointArray[endY + endX                * obstacleGrid[0].length], list, obstacleGrid);        return resultList.size();    }    private void caclPath(Point[] pointArray, Point currentPoint,            Point targetPoint, ArrayList<Point> pointList, int[][] obstacleGrid) {        if (alreadyPath != -1 && alreadyPath < pointList.size()) {            return;        }        if (currentPoint == targetPoint) {            ArrayList<Point> tempList = (ArrayList<Point>) pointList.clone();            if (tempList.size() < alreadyPath) {                resultList = new ArrayList<ArrayList<Point>>();            }            alreadyPath = tempList.size();            resultList.add(tempList);            currentPoint.IsCheck = false;            return;        } else {            ArrayList<Point> pointArrayTemp = currentPoint.getAroundPoint(                    pointArray, obstacleGrid, targetPoint);            for (int i = 0; i < pointArrayTemp.size(); ++i) {                pointList.add(pointArrayTemp.get(i));                pointArrayTemp.get(i).IsCheck = true;                caclPath(pointArray, pointArrayTemp.get(i), targetPoint,                        pointList, obstacleGrid);                pointArrayTemp.get(i).IsCheck = false;                pointList.remove(pointArrayTemp.get(i));            }        }    }    /**     * 组成点对象     *      * @param obstacleGrid     * @return     */    private Point[] constructPointArray(int[][] obstacleGrid) {        Point[] arrayPoint = new Point[obstacleGrid.length                * obstacleGrid[0].length];        Point point = null;        for (int i = 0; i < obstacleGrid.length; ++i) {            for (int k = 0; k < obstacleGrid[0].length; ++k) {                point = new Point();                point.X = i;                point.Y = k;                point.IsCheck = false;                point.value = obstacleGrid[i][k];                arrayPoint[k + i * obstacleGrid[0].length] = point;            }        }        return arrayPoint;    }    private class Point {        public int X;        public int Y;        public boolean IsCheck;        public int value;        /**         * 获取某个点接下来可走的位置         *          * @param pointArray         * @param obstacleGrid         * @param targetPoint         * @return         */        private ArrayList<Point> getAroundPoint(Point[] pointArray,                int[][] obstacleGrid, final Point targetPoint) {            Point original = this;            ArrayList<Point> arraylist = new ArrayList<Point>();            Point point = null;            // 上            if (original.X - 1 >= 0                    && pointArray[(original.X - 1) * obstacleGrid[0].length                            + original.Y].value != 1                    && !pointArray[(original.X - 1) * obstacleGrid[0].length                            + original.Y].IsCheck) {                // 说明点可以走                point = pointArray[(original.X - 1) * obstacleGrid[0].length                        + original.Y];                arraylist.add(point);            }            // 下            if (original.X + 1 < obstacleGrid.length                    && pointArray[(original.X + 1) * obstacleGrid[0].length                            + original.Y].value != 1                    && !pointArray[(original.X + 1) * obstacleGrid[0].length                            + original.Y].IsCheck) {                // 说明点可以走                point = pointArray[(original.X + 1) * obstacleGrid[0].length                        + original.Y];                arraylist.add(point);            }            // 左            if (original.Y - 1 >= 0                    && pointArray[(original.X) * obstacleGrid[0].length                            + original.Y - 1].value != 1                    && !pointArray[(original.X) * obstacleGrid[0].length                            + original.Y - 1].IsCheck) {                // 说明点可以走                point = pointArray[(original.X) * obstacleGrid[0].length                        + original.Y - 1];                arraylist.add(point);            }            // 右            if (original.Y + 1 < obstacleGrid[0].length                    && pointArray[(original.X) * obstacleGrid[0].length                            + original.Y + 1].value != 1                    && !pointArray[(original.X) * obstacleGrid[0].length                            + original.Y + 1].IsCheck) {                // 说明点可以走                point = pointArray[(original.X) * obstacleGrid[0].length                        + original.Y + 1];                arraylist.add(point);            }            return arraylist;        }    }}

总结

   这个算法是我认为最有意思的一个算法,它可以做路径查找的小游戏,在对战类的游戏中有很大的帮助,本文的缺陷是,递归方案使得时间耗时严重,后续会继续对其进行优化,有好的思路请留言告知。
0 0