Recursion 二维空间里机器人向右或向下走的所有路径问题 @CareerCup

来源:互联网 发布:免费建立淘宝客网站 编辑:程序博客网 时间:2024/06/08 15:03

这道题学到了在做回溯时,先把点加入到path中,然后根据子情况来决定success这个变量,从而决定之前加入的点是否有必要的。如果子情况返回的是false,则这个点也没有必要加入到path中,就可以移除了。

还有一个是,我的解答中每次函数只对当前点进行isFree的判断,官方答案中却对下一个节点进行判断。我还是觉得我的更直观一些。


package Recursion;import java.awt.Point;import java.util.ArrayList;import java.util.Hashtable;import CtCILibrary.AssortedMethods;/** * Imagine a robot sitting on the upper left comer of an X by Ygrid. The robot * can only move in two directions: right and down. How many possible paths are * there for the robot to go from (0, 0) to (X, Y) ? *  * 在一个N*N矩阵的左上角坐着一个机器人,它只能向右运动或向下运动。那么, 机器人运动到右下角一共有多少种可能的路径?进一步地,如果对于其中的一些格子,机器人是不能踏上去的。设计一种算法来获得所有可能的路径。 *  */public class S9_2 {public static int[][] maze = new int[10][10];public static void main(String[] args) {maze = AssortedMethods.randomMatrix(10, 10, 0, 4);AssortedMethods.printMatrix(maze);ArrayList<Point> path = new ArrayList<Point>();boolean success = getPathRec(9, 9, path);ArrayList<Point> pathRef = new ArrayList<Point>();boolean successRef = getPathRef(9, 9, pathRef);Hashtable<Point, Boolean> cache = new Hashtable<Point, Boolean>();ArrayList<Point> pathDP = new ArrayList<Point>();getPathMemo(9, 9, pathDP, cache);if (success) {String s = AssortedMethods.listOfPointsToString(path);System.out.println(s);System.out.println(AssortedMethods.listOfPointsToString(pathRef));System.out.println(AssortedMethods.listOfPointsToString(pathDP));} else {System.out.println("No path found.");}}// 返回是否成功获得一条路径public static boolean getPathRec(int x, int y, ArrayList<Point> path) {boolean free = isFree(x, y);// 检查是否当前位置是合法的boolean success = false;// 表示成功获得路径path.add(new Point(x, y));// 可以采用先加入,如果后面的success为false则移除的方法!if(x==0 && y==0 && free){// 到达初始点,找到路径return true;}if(x == 0 && free){// 第一行success = getPathRec(x, y-1, path);}if(y == 0 && free){// 第一列success = getPathRec(x-1, y, path);}if(x>0 && y>0 && free){// 中间位置success = getPathRec(x-1, y, path);// 先尝试往上走if( !success ){// 如果往上走不得再尝试往左走success = getPathRec(x, y-1, path);}}if(!success){// 如果所有尝试都失败了,证明当前节点不适合,因此移除!path.remove(path.size()-1);}return success;}public static boolean getPathMemo(int x, int y, ArrayList<Point> path, Hashtable<Point, Boolean> ht) {boolean free = isFree(x, y);// 检查是否当前位置是合法的boolean success = false;// 表示成功获得路径path.add(new Point(x, y));// 可以采用先加入,如果后面的success为false则移除的方法!Point p = new Point(x, y);if(ht.contains(p)){// 利用cache预先判断return ht.get(p);}if(x==0 && y==0 && free){// 到达初始点,找到路径return true;}if(x == 0 && free){// 第一行success = getPathMemo(x, y-1, path, ht);}if(y == 0 && free){// 第一列success = getPathMemo(x-1, y, path, ht);}if(x>0 && y>0 && free){// 中间位置success = getPathMemo(x-1, y, path, ht);// 先尝试往上走if( !success ){// 如果往上走不得再尝试往左走success = getPathMemo(x, y-1, path, ht);}}if(!success){// 如果所有尝试都失败了,证明当前节点不适合,因此移除!path.remove(path.size()-1);}return success;}public static boolean isFree(int x, int y){return maze[x][y] != 0;}// 官方答案public static boolean getPathRef(int x, int y, ArrayList<Point> path) {Point p = new Point(x, y);path.add(p);if (x == 0 && y == 0) {return true; // found a path}boolean success = false;if (x >= 1 && isFree(x - 1, y)) { // Try rightsuccess = getPathRef(x - 1, y, path); // Free!  Go right}if (!success && y >= 1 && isFree(x, y - 1)) { // Try downsuccess = getPathRef(x, y - 1, path); // Free!  Go down}if (!success) {path.remove(p); // Wrong way! Better stop going this way}return success;}}


原创粉丝点击