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
- Java 实现最优路径查找算法(伪Leetcode路径查找算法)
- Dijastra最优路径算法
- 使用栈和队列实现迷宫路径查找算法
- 查找算法Java实现
- Dijkstra最优路径的算法
- Dijkstra最优路径的算法
- 算法:查找----二分查找(Java实现)
- [查找算法]--二分查找的Java实现
- Java实现二分查找算法
- java 二分查找算法实现
- 二分查找算法java实现
- 常见查找算法Java实现
- 二分查找算法----java实现
- 常见查找算法(Java实现)
- java实现常见查找算法
- Java实现二分查找算法
- 算法导论15.5最优二叉查找树实现(Java语言)
- java最优有序查找——红黑树(RBT)算法
- tcpdump
- Android Data Binding 高级用法
- 第八周实践都要学C
- vim delete
- Ubuntu 18.10可能取消对 32 位的支持!
- Java 实现最优路径查找算法(伪Leetcode路径查找算法)
- JZOJ 4822. 【NOIP2016提高A组集训第1场10.29】完美标号
- 编程常识
- 深入剖析Ehcache开源缓存框架
- Android中自定义控件
- SQL concept
- Git分支的前世今生
- mysql 忘记密码怎么办
- Git的使用