• Java 通过回溯实现 全排列 和 N皇后问题



    这两个问题的主体思路就为回溯,而回溯算法的框架就可以大致概括为:

    def 满足的结束条件:
    	result.add(路径);将符合条件的结果先保存起来
    	return
    	
    	for 选择 in 选择列表:
    		做选择
    		backtrack(路径,选择列表)
    		撤销选择
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    路径:就是已经做出的选择
    选择列表:当前还可以做的选择
    结束条件:达到决策树的底层,也就是做完了所有的决策,没有条件了。

    下来就看具体的题目

    全排列问题 (力扣、46)

    给定一个不含重复数字的数组 nums ,返回其所有可能的全排列 。你可以 按任意顺序 返回答案。

    示例 1:
    输入:nums = [1,2,3]
    输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

    示例 2:
    输入:nums = [0,1]
    输出:[[0,1],[1,0]]

    示例 3:
    输入:nums = [1]
    输出:[[1]]

    多余的解释就不说了,详细的理解步骤过程都在代码注释里面。

    import java.util.LinkedList;
    import java.util.List;
    
    public class Demo46 {
        public static void main(String[] args) {
            int[] nums = {1, 2, 3};
            List<List<Integer>> lists = permute(nums);
            System.out.println(lists);
        }
    
        public static List<List<Integer>> res = new LinkedList<>();
    
        public static List<List<Integer>> permute(int[] nums) {
            //list记录当前正在走的路径
            LinkedList<Integer> list = new LinkedList<>();
            backtrack(nums, list);
            return res;
        }
    
        public static void backtrack(int[] nums, LinkedList<Integer> list) {
            // 触发结束条件
            if (list.size() == nums.length) {
                res.add(new LinkedList(list));//路径走到底了,就保存当前路径
                return;
            }
    
            for (int i = 0; i < nums.length; i++) {
                // 将已经走过的路径排除掉
                if (list.contains(nums[i])) {
                    continue;
                }
                //选择下面要走的路径
                list.add(nums[i]);
                //递归向下,进入下一个决策树
                backtrack(nums, list);
                // 删除集合当中最后一个元素
                list.removeLast();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    在这里插入图片描述

    N皇后问题(力扣、51)

    按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
    n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

    给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
    每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。

    输入:n = 4
    输出:[[“.Q…”,“…Q”,“Q…”,“…Q.”],[“…Q.”,“Q…”,“…Q”,“.Q…”]]
    在这里插入图片描述

    解释:如上图所示,4 皇后问题存在两个不同的解法。

    详解看代码注释:

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.LinkedList;
    import java.util.List;
    
    public class Demo51 {
        public static void main(String[] args) {
            int n = 4;
            List<List<String>> lists = solveNQueens(n);
            System.out.println(lists);
        }
    
        public static List<List<String>> res = new ArrayList<>();
    
        public static List<List<String>> solveNQueens(int n) {
            // 初始化棋盘
            char[][] chars = new char[n][n];
            for (int i = 0; i < n; i++) {
                Arrays.fill(chars[i], '.');
            }
            backtrack(chars, 0);
            return res;
        }
    
    	//回溯计算结果
        public static void backtrack(char[][] chars, int row) {
            // 触发结束条件,记录成功的结果
            if (row == chars.length) {
                res.add(charToList(chars));//记录结果
                return;
            }
    
            for (int i = 0; i < chars.length; i++) {
                // 判断当前位置是否可以放入皇后
                if (!isValid(chars, row, i)) {
                    continue;
                }
                // 确定可以放皇后
                chars[row][i] = 'Q';
                // 进入下一行判断
                backtrack(chars, row + 1);
                // 上面递归判断完成,清理棋盘
                chars[row][i] = '.';
            }
        }
    
    	//判断是否符合条件
        public static boolean isValid(char[][] chars, int row, int col) {
            int len = chars.length;
            // 列里面是否有冲突
            for (int i = 0; i < row; i++) {
                if (chars[i][col] == 'Q') {
                    return false;
                }
            }
            //右上是否有冲突
            for (int i = row - 1, j = col + 1; i >= 0 && j < len; i--, j++) {
                if (chars[i][j] == 'Q') {
                    return false;
                }
            }
            // 左上是否有冲突
            for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
                if (chars[i][j] == 'Q') {
                    return false;
                }
            }
            return true;
        }
    
        // 记录返回结果
        public static List charToList(char[][] chars) {
            List<String> list = new LinkedList<>();
            for (char[] c : chars) {
                list.add(String.copyValueOf(c));
            }
            return list;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79

    在这里插入图片描述

  • 相关阅读:
    操作系统学习笔记1 | 初识操作系统
    阿里二面:谈谈ThreadLocal的内存泄漏问题?问麻了。。。。
    论文解读(MGAE)《MGAE: Masked Autoencoders for Self-Supervised Learning on Graphs》
    CV | 360BEV: Panoramic Semantic Mapping for Indoor Bird‘s-Eye View理解
    十二月,我们一起在云台山风景区赏雪
    6.axios、json-server基本使用
    程序员个性终端指南(cmder、powershell、window terminal)
    解决WebStorm中不显示npm任务面板
    易动纷享--测试实习生视频面试
    【前端升全栈】 五分钟了解Node.js
  • 原文地址:https://blog.csdn.net/weixin_45970271/article/details/126069071