• LeetCode——N皇后 II


    Q:n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

    给定一个整数 n,返回 n 皇后不同的解决方案的数量。

    示例:
    输入: 4
    输出: 2
    解释: 4 皇后问题存在如下两个不同的解法。
    [
     [".Q..",  // 解法 1
      "...Q",
      "Q...",
      "..Q."],

    ["..Q.",  // 解法 2
      "Q...",
      "...Q",
      ".Q.."]
    ]

    提示:皇后,是国际象棋中的棋子,意味着国王的妻子。皇后只做一件事,那就是“吃子”。当她遇见可以吃的棋子时,就迅速冲上去吃掉棋子。当然,她横、竖、斜都可走一或七步,可进可退。(引用自 百度百科 - 皇后 )

    A:
    同I中的回溯法

        private int result;
    
        public int totalNQueens(int n) {
            if (n <= 1)
                return n;
            ArrayList<Integer> l = new ArrayList<>();
            result = 0;
            help(0, n, l);
            return result;
        }
    
        private void help(int row, int n, ArrayList<Integer> l) {
            if (row == n) {
                result++;
                return;
            }
            for (int col = 0; col < n; col++) {
                if (!l.contains(col)) {
                    if (!isDiagonal(l, col)) {
                        l.add(col);
                        help(row + 1, n, l);
                        l.remove(l.size() - 1);
                    }
                }
            }
        }
    
        private boolean isDiagonal(ArrayList<Integer> l, int col) {
            int currRow = l.size();
            for (int row = 0; row < l.size(); row++) {
                if (Math.abs(currRow - row) == Math.abs(col - l.get(row))) {
                    return true;
                }
            }
            return false;
        }
    

    2.如果是面试,上面那种就ok了。还有一种位运算的方法,(但我位运算学的一直不好,就没仔细看)
    借鉴:使用 bitmap 回溯

      public int backtrack(int row, int hills, int next_row, int dales, int count, int n) {
        /** 
         row: 当前放置皇后的行号
         hills: 主对角线占据情况 [1 = 被占据,0 = 未被占据]
         next_row: 下一行被占据的情况 [1 = 被占据,0 = 未被占据]
         dales: 次对角线占据情况 [1 = 被占据,0 = 未被占据]
         count: 所有可行解的个数
         */
    
        // 棋盘所有的列都可放置,
        // 即,按位表示为 n 个 '1'
        // bin(cols) = 0b1111 (n = 4), bin(cols) = 0b111 (n = 3)
        // [1 = 可放置]
        int columns = (1 << n) - 1;
    
        if (row == n)   // 如果已经放置了 n 个皇后
          count++;  // 累加可行解
        else {
          // 当前行可用的列
          // ! 表示 0 和 1 的含义对于变量 hills, next_row and dales的含义是相反的
          // [1 = 未被占据,0 = 被占据]
          int free_columns = columns & ~(hills | next_row | dales);
    
          // 找到可以放置下一个皇后的列
          while (free_columns != 0) {
            // free_columns 的第一个为 '1' 的位
            // 在该列我们放置当前皇后
            int curr_column = - free_columns & free_columns;
    
            // 放置皇后
            // 并且排除对应的列
            free_columns ^= curr_column;
    
            count = backtrack(row + 1,
                    (hills | curr_column) << 1,
                    next_row | curr_column,
                    (dales | curr_column) >> 1,
                    count, n);
          }
        }
    
        return count;
      }
      public int totalNQueens(int n) {
        return backtrack(0, 0, 0, 0, 0, n);
      }
    
  • 相关阅读:
    MySQL5.7.24安装配置
    MySQL_5.1安装图解
    在前端用json数据绑定下拉框
    在前端遍历DataGrid获取数据
    选项卡的使用
    系统中的数字表示用枚举
    我们ERP中在表格里实现全选
    使用委托在事务提交完以后执行
    树形列表搜索逐单行搜索
    文件上传-zip软链接
  • 原文地址:https://www.cnblogs.com/xym4869/p/13139421.html
Copyright © 2020-2023  润新知