赞
踩
int main(){
finalresult = [] // 存放答案的所有种情况
backtrack(路径,1/选择列表) // 从第一层开始找,路径为当前正在寻找的某一种答案的记录
}
// 回溯-递归
void backtrack(路径,深度/选择列表)
if( (深度)满足结束条件/选择列表为空)
finalresult.add(路径) // 递归到了最深的一层,此时找到了一张答案,将其存储在finalresult中
return
for 选择 in 选择列表: // 遍历可以选择的所有情况
做选择(并判断当前选择是否满足情况 ifxxx continue)
backtrack(路径, 深度+1 /新选择列表)
撤销选择
}
路径:当前搜索记录的一条路径
深度:搜索的进度(树的深度)
下面是完全利用上述框架实现的两道经典例题
LeetCode地址:https://leetcode.cn/problems/permutations/
package leetcode.editor.cn; import javax.sound.midi.Track; import java.util.*; /** * 全排列 * @author WZP * @date 2023-03-21 16:46:06 */ public class P46_Permutations{ public static void main(String[] args) { //测试代码 Solution solution = new P46_Permutations().new Solution(); solution.permute(new int[]{1, 2, 3}); // 测试1 2 3 全排列 } //力扣代码 //leetcode submit region begin(Prohibit modification and deletion) class Solution { List<List<Integer>> finalresult = new ArrayList<List<Integer>>(); int N; boolean[] booleans; int[] nums; public List<List<Integer>> permute(int[] nums) { this.nums = nums; List<Integer> result = new LinkedList<>(); booleans = new boolean[nums.length]; N = nums.length; backtrack(result,0); return finalresult; } public void backtrack(List<Integer> result,int n){ // 满足结束条件 if(n == N){ finalresult.add(new LinkedList<>(result)); // 必须新new一个添加到finalresult中,否则只是添加了引用的地址 return; } // 遍历可以选择的所有情况 for (int i = 0; i < nums.length;i++){ // 做选择(并判断当前选择是否满足情况) if(booleans[i]){ // 判断是否已经用过 continue; // 是,则排除 } result.add(nums[i]); booleans[i] = true; // 标记为已用过 // 递归 backtrack(result,n+1); // 寻找下一个数 // 撤销选择 result.remove(result.size()-1); booleans[i] = false; } } } //leetcode submit region end(Prohibit modification and deletion) }
LeetCode题目地址:https://leetcode.cn/problems/n-queens/
package leetcode.editor.cn; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * N 皇后 * @author WZP * @date 2023-03-21 */ public class P51_NQueens{ public static void main(String[] args) { //测试代码 Solution solution = new P51_NQueens().new Solution(); solution.solveNQueens(4); } //力扣代码 //leetcode submit region begin(Prohibit modification and deletion) class Solution { List<List<String>> finalresult = new ArrayList<>(); int N; public List<List<String>> solveNQueens(int n) { int[] result = new int[n+1]; // 注意下标从1开始,result[n]表示第n行存在的位置是第result[n]个 N = n; // N皇后,保存N的值 backtrack(result,1); // 从第一行开始找 return finalresult; } public void backtrack(int[] result,int n){ // 满足结束条件 if( n > N ){ finalresult.add(generateString(result)); // 将数组结果转换为满足题目要求的string结果 return; } // 遍历可以选择的所有情况 for 选择 in 选择列表: for(int i = 1; i <= N; i++){ // 判断棋盘第n行的1-N种选择 // 做选择,排除不合法选择 result[n] = i;// 选择第i个 if(!PLACE(n,result)) { // 判断是否与之前的点处在同一列或者同一斜线 continue;// 是 则排除 } // 递归,进入下一层决策树 backtrack(result,n + 1); //继续向更深一层找(继续向下一行找) // 撤销选择 result[n] = 0; } } /** * 将其中一个解的答案转换为List<String>:将数组存放的答案转换为用List<String>列表字符串存储 * @param queens * @return List<String> */ public List<String> generateString(int[] queens){ // 注意,queens中的下标从1开始 List<String> result=new ArrayList<>(); for(int i =1;i < queens.length;i++){ char[] chars=new char[queens.length-1]; Arrays.fill(chars,'.'); chars[queens[i]-1]='Q'; result.add(String.valueOf(chars)); } return result; } /** * 判断当前k行的选择节点result[k]的与k行之前行选择的位置是否满足要求 * @param k * @return boolean */ public boolean PLACE(int k,int[] result) { for (int i = 1;i<k;i++){ // 判断result[k]的正上方没有节点,并且不在一条斜线 if ((result[k]==result[i])||(Math.abs(k - i)==Math.abs(result[k]-result[i]))){ return false; } } return true; } } //leetcode submit region end(Prohibit modification and deletion) }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。