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

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;
        }
    }
}

总结

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值