回溯问题,我不知道我解决它的计划是否正确
Backtracking prorblem and I don't know if my plan to solve it is correct
我正在练习一个回溯问题,这里是问题描述:
https://practiceit.cs.washington.edu/problem/view/cs2/sections/recursivebacktracking/travel
编写一个travel方法,接受整数x和y作为参数,并使用递归回溯打印二维平面中从(0, 0)到(x, y)的所有解决方案,重复使用其中一个三招:
东(E):右移1(增加x)
北(N):向上移动 1(增加 y)
东北 (NE):向上移动 1 向右移动 1(增加 x 和 y)。
这是我得到的:
我让它在一条路径上工作,但我不确定如何让它去探索所有其他可能的路径。我认为我的基本案例设计是错误的,但我不确定。我只想知道我应该首先解决什么问题,是基本情况还是我的整个概念都是错误的。
public class PracticeRecordCode {
public static void main(String[] args) {
travel(1, 2);
}
public static String travel(int x, int y){
List<String> allpath = new ArrayList<String>();
String eachpath = "";
return explore(0, 0, x, y, eachpath, allpath);
}
public static String explore(int x, int y, int des_x, int dest_y, String eachPath, List<String> allpath) {
//Base case
if(x == des_x && y== dest_y) {
String result = "";
if(isRepeated(eachPath, allpath)){
allpath.add(eachPath);
eachPath = "";
}
// Print all content from allpath
for (String path : allpath) {
result += path + "\n";
System.out.println(path);
}
return result;
} else {
if(x == des_x && y != dest_y){
eachPath += "N ";
if(!allpath.contains(eachPath)) {
allpath.add(eachPath);
}
explore(x, y+1, des_x, dest_y, eachPath, allpath);
} else if(x != des_x && y == dest_y) {
eachPath += "E ";
allpath.add(eachPath);
explore(x + 1, y, des_x, dest_y, eachPath, allpath);
} else {
eachPath += "NE ";
allpath.add(eachPath);
explore(x + 1, y+1, des_x, dest_y, eachPath, allpath);
}
}
return "";
}
// Check if this path has been done already
public static boolean isRepeated(String path, List<String> allpath){
return allpath.contains(path);
}
}
你可以试试我的代码。希望它能给你解决方案->
public static void main(String[] args) {
baktracking(new boolean[5][3], 0, 0, 2, 2, "");
}
static void baktracking(boolean m[][], int x, int y, int dx, int dy, String ans) {
if (x == dx && y == dy) {
System.out.println(ans);
return;
}
if (x < 0 || y < 0 || x >= m.length || y >= m[0].length) {
return;
}
m[x][y] = true;
baktracking(m, x, y +1, dx, dy, ans + "E" + " ");
baktracking(m, x + 1, y, dx, dy, ans + "N" + " ");
baktracking(m, x + 1, y + 1, dx, dy, ans + "NE" + " ");
m[x][y] = false;
}
我们可以对您的 explore
方法进行一些改进,因为您的实施存在一些缺陷。退出条件有两个: 1. 当你到达目的地时,这是一条有效的路径,我们可以将其保存到你的最终结果中。 2. 你到达了目的地(x>des_x || y>dest_y)
,这意味着这是一条无效的路径,我们不必再继续探索了。否则,您有 3 个选项可以继续探索:E、N 或 NE。由于每个方向都是独一无二的,您不必担心重复。
完成所有可能的探索后,您的 allpath
列表将添加所有有效路径。您可以 return 列表或打印它。
基于此,您的代码可以像这样简单得多:
import java.util.ArrayList;
import java.util.List;
public class PracticeRecordCode {
public static void main(String[] args) {
travel(2, 2);
}
public static void travel(int x, int y){
List<String> allpath = new ArrayList<String>();
explore(0, 0, x, y, "", allpath);
// Print all content from allpath
for (String path : allpath) {
System.out.println(path);
}
}
public static void explore(int x, int y, int des_x, int dest_y, String eachPath, List<String> allpath) {
//Base case
if(x == des_x && y == dest_y) {
allpath.add(eachPath);
return;
}
if(x>des_x || y>dest_y)
return;
explore(x + 1, y, des_x, dest_y, eachPath + "E ", allpath);
explore(x, y+1, des_x, dest_y, eachPath + "N ", allpath);
explore(x + 1, y+1, des_x, dest_y, eachPath + "NE ", allpath);
}
}
我正在练习一个回溯问题,这里是问题描述: https://practiceit.cs.washington.edu/problem/view/cs2/sections/recursivebacktracking/travel
编写一个travel方法,接受整数x和y作为参数,并使用递归回溯打印二维平面中从(0, 0)到(x, y)的所有解决方案,重复使用其中一个三招:
东(E):右移1(增加x) 北(N):向上移动 1(增加 y) 东北 (NE):向上移动 1 向右移动 1(增加 x 和 y)。
这是我得到的: 我让它在一条路径上工作,但我不确定如何让它去探索所有其他可能的路径。我认为我的基本案例设计是错误的,但我不确定。我只想知道我应该首先解决什么问题,是基本情况还是我的整个概念都是错误的。
public class PracticeRecordCode {
public static void main(String[] args) {
travel(1, 2);
}
public static String travel(int x, int y){
List<String> allpath = new ArrayList<String>();
String eachpath = "";
return explore(0, 0, x, y, eachpath, allpath);
}
public static String explore(int x, int y, int des_x, int dest_y, String eachPath, List<String> allpath) {
//Base case
if(x == des_x && y== dest_y) {
String result = "";
if(isRepeated(eachPath, allpath)){
allpath.add(eachPath);
eachPath = "";
}
// Print all content from allpath
for (String path : allpath) {
result += path + "\n";
System.out.println(path);
}
return result;
} else {
if(x == des_x && y != dest_y){
eachPath += "N ";
if(!allpath.contains(eachPath)) {
allpath.add(eachPath);
}
explore(x, y+1, des_x, dest_y, eachPath, allpath);
} else if(x != des_x && y == dest_y) {
eachPath += "E ";
allpath.add(eachPath);
explore(x + 1, y, des_x, dest_y, eachPath, allpath);
} else {
eachPath += "NE ";
allpath.add(eachPath);
explore(x + 1, y+1, des_x, dest_y, eachPath, allpath);
}
}
return "";
}
// Check if this path has been done already
public static boolean isRepeated(String path, List<String> allpath){
return allpath.contains(path);
}
}
你可以试试我的代码。希望它能给你解决方案->
public static void main(String[] args) {
baktracking(new boolean[5][3], 0, 0, 2, 2, "");
}
static void baktracking(boolean m[][], int x, int y, int dx, int dy, String ans) {
if (x == dx && y == dy) {
System.out.println(ans);
return;
}
if (x < 0 || y < 0 || x >= m.length || y >= m[0].length) {
return;
}
m[x][y] = true;
baktracking(m, x, y +1, dx, dy, ans + "E" + " ");
baktracking(m, x + 1, y, dx, dy, ans + "N" + " ");
baktracking(m, x + 1, y + 1, dx, dy, ans + "NE" + " ");
m[x][y] = false;
}
我们可以对您的 explore
方法进行一些改进,因为您的实施存在一些缺陷。退出条件有两个: 1. 当你到达目的地时,这是一条有效的路径,我们可以将其保存到你的最终结果中。 2. 你到达了目的地(x>des_x || y>dest_y)
,这意味着这是一条无效的路径,我们不必再继续探索了。否则,您有 3 个选项可以继续探索:E、N 或 NE。由于每个方向都是独一无二的,您不必担心重复。
完成所有可能的探索后,您的 allpath
列表将添加所有有效路径。您可以 return 列表或打印它。
基于此,您的代码可以像这样简单得多:
import java.util.ArrayList;
import java.util.List;
public class PracticeRecordCode {
public static void main(String[] args) {
travel(2, 2);
}
public static void travel(int x, int y){
List<String> allpath = new ArrayList<String>();
explore(0, 0, x, y, "", allpath);
// Print all content from allpath
for (String path : allpath) {
System.out.println(path);
}
}
public static void explore(int x, int y, int des_x, int dest_y, String eachPath, List<String> allpath) {
//Base case
if(x == des_x && y == dest_y) {
allpath.add(eachPath);
return;
}
if(x>des_x || y>dest_y)
return;
explore(x + 1, y, des_x, dest_y, eachPath + "E ", allpath);
explore(x, y+1, des_x, dest_y, eachPath + "N ", allpath);
explore(x + 1, y+1, des_x, dest_y, eachPath + "NE ", allpath);
}
}