刷题38-N皇后问题

原题链接

题目描述

N皇后问题是把N个皇后放在一个N×N棋盘上,使皇后之间不会互相攻击。
即任意两个皇后都不能处于同一行、同一列或同一对角线上(正反)。

在这里插入图片描述

示例

输入:
4
输出:
[".Q..",  // 解法 1
  "...Q",
  "Q...",
  "..Q."],

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

解析

  1. 3皇后问题的图解分析(3皇后问题无解)
    在这里插入图片描述

  2. 可用一维数组array[]表示N皇后问题的解,array[i]的值表示第i行的皇后所在的列号。例如一个满足要求的四皇后棋盘布局如下图所示,其结果array数组的值为:[2, 4, 1, 3]。
    在这里插入图片描述

  3. 判定当前结点棋盘布局是否符合要求
    (1)array[i] == array[j],则第i行与第j行皇后在同一列上。
    (2)如果第i行的皇后在第s列,第j行皇后在第t列,即array[i] = s和array[j] = t,只要|i-j| == |s-t|(横纵坐标相减的绝对值相等),则皇后在同一对角线上。

  4. 遍历中要随时判定当前结点棋盘布局是否符合要求,符合要求则继续向下层遍历,直至判断得到一个满足约束条件的叶子结点(即到了最后一层),从而获得一个满足要求的棋盘布局;不符合要求的结点将被舍弃(称之为剪枝),并回溯到上一层的结点(上一层的循环)继续遍历。

参考解法

import java.util.ArrayList;
import java.util.Arrays;

public class Test {
    
    
    // 放在方法外,全局变量
    ArrayList<String[]> list=new ArrayList<String[]>();

    /**
     * @param n
     * @return
     */
    public ArrayList<String[]> solveNQueens(int n) {
    
    
        if(n<=0){
    
    
            return list;
        }
        int[] array=new int[n];
        method(array,0);
        return list;
    }

    /**
     * 迭代过程
     * @param array 表示皇后的位置,array[i] = j, 表示皇后Q在第i行、第j列
     * @param k
     */
    public void method(int[] array,int k){
    
    
        // 表示将皇后放在了最后一行,已经生成了一个解
        if(k==array.length){
    
    
            String[] s=new String[array.length];
            for(int i=0;i<array.length;i++){
    
    
                char[] ca=new char[array.length];
                Arrays.fill(ca,'.');
                ca[array[i]]='Q';
                s[i]=new String(ca);
            }
            list.add(s);
            return ;
        }

        for(int i=0;i<array.length;i++){
    
    
            // 将皇后Q放在第k行,第i列
            array[k]=i;
            // 满足条件则继续放在下一行
            if(check(array,k)){
    
    
                method(array,k+1);
            }
        }

    }

    /**
     * 判断当前结点棋盘布局是否符合要求
     * @param array 表示皇后的位置,array[i] = j, 表示皇后Q在第i行、第j列
     * @param k
     * @return
     */
    public boolean check(int[] array,int k){
    
    
        for(int i=0;i<k;i++){
    
    
            // 前面判断皇后是否在同一列
            // 后面判断是否在同一对角线(正反)。 处于对角线上的点,的横纵坐标的差,的绝对值,是相等的
            if(array[i]==array[k]||k-i==Math.abs(array[i]-array[k])){
    
    
                return false;
            }
        }
        return true;
    }
}

参考博客

https://blog.csdn.net/weixin_39651041/article/details/79972829

猜你喜欢

转载自blog.csdn.net/Awt_FuDongLai/article/details/110506445