说明
回溯问题,实际上决策树遍历问题。只需思考3个问题:
- 路径:已做的选择;
- 选择列表:当前可以做的选择;
- 结束条件:无法再做选择的条件。
框架
result = []def backtrack(路径, 选择列表):if 满足结束条件:result.add(路径)returnfor 选择 in 选择列表:做选择backtrack(路径, 选择列表)撤销选择
全排列问题
获取全排列的所有路径。这里假设n个数都不相同,则共有n!条路径。

List<List<Integer>> res = new LinkedList<>();List<List<Integer>> permute(int[] nums) {LinkedList<Integer> track = new LinkedList<>();backtrace(nums, track);return res;}void backtrack(int[] nums, LinkedList<Integer> track) {// 结束 触发if(tack.size() == nums.length) {res.add(new LinkedList(track));return;}for(int i = 0; i < nums.length; i++) {// 排除不合法的选择if(track.contains(nums[i]))continue;// 做选择track.add(nums[i]);// 进入下一层决策树backtrack(nums, track);// 撤销选择track.reomveLast();}}
N 皇后问题
给你一个 N×N 的棋盘,让你放置 N 个皇后,使得它们不能互相攻击。皇后可以攻击同一行、同一列、左上左下右上右下四个方向的任意单位。

List<List<String>> res = new LinkedList<>();// 输入 棋盘 边长n , 返回所有的 合法 放置List<List<String>> solveNQueues(int n) {// '.' 表示空, 'Q'表示皇后 初始化空棋盘List<String> borad;backtrack(board, 0);return res}// 路径: board中 小于row的那些行已经成功放置了皇后// 选择列表: 第row行所以的列都是放置皇后的选择// 结束条件:row 超过 board 的最后一行void backtrack(List<String> board, int row) {// 已经超过最后一行,保存当前棋盘的状况if(row == board.size()) {res.add(board);return;}// 一行就是一个字符串 获取长度int len = board.get(row).length();for(int col = 0; col < len; col++) {
