N皇后问题

LeetCode 51 N皇后
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
在这里插入图片描述

上图为 8 皇后问题的一种解法。

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

每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。

解法思路:递归+回溯
1、从第0行,第0列开始插入皇后
2、行数++
3、依次遍历当前行所有列找到允许插入的列插入皇后,当前网格数记为1,重复2~3
4、若遍历完当前行所有列没有找到能插入的点,则结束当前方法返回上一层,在上一层寻找下一个能插入的点,重复2~4
5、直至当前行数已经遍历完成,存入list中,并返回上一层寻找下一个能插入的点,重复2~5

class Solution {
    List<List<String>> list = new ArrayList<>();
    
    public List<List<String>> solveNQueens(int n) {
         int [][] grid = new int [n][n];
         
         HashSet<Integer> column = new HashSet<>();
         //左上到右下-7~7(x-y)
         HashSet<Integer> line1 = new HashSet<>(); 
         //右上到左下0~14(x+y)
         HashSet<Integer> line2 = new HashSet<>(); 
         dfs(grid,0,n,column,line1,line2);
         return list;
       
    }
    public void dfs(int [][] grid,int i,int n,HashSet<Integer> column
    ,HashSet<Integer> line1,HashSet<Integer> line2){
        if(i >= n){
            toAdd(grid,n);
            return ;
        }
        for(int y = 0; y < n; y++){
            if(column.contains(y) || line1.contains(i-y) || line2.contains(i+y)){
                continue;
            }
            grid[i][y] = 1;
            column.add(y);
            line1.add(i-y);
            line2.add(i+y);
            dfs(grid,i+1,n,column,line1,line2);
            grid[i][y] = 0;
            column.remove(y);
            line1.remove(i-y);
            line2.remove(i+y);
            
        }
    }
   

   public void toAdd(int [][] grid,int n){
      List<String> list2 = new ArrayList<>(); 
       for(int i = 0; i < n; i++){
           String s = "";
           for(int j = 0; j < n; j++){
               if(grid[i][j] == 1){
                   s += "Q";
               }else{
                   s += ".";
               }
           }
           list2.add(s);
       }
       list.add(list2);
   }
}

N皇后的解决方案数,方法类似

class Solution { 
    int resulut = 0;
    
    public int totalNQueens(int n) {
       boolean [] line = new boolean [n];
       int [] p = new int [n]; 
       int row = 0;
       dfs(0,n,line,p);
       return resulut;
    }
    public void dfs(int row, int n, boolean [] line, int [] p){
        if(row >= n){
            resulut++;
            return;
        }
        for(int i = 0; i < n; i++){
            boolean flag = true;
            if(!line[i]){
                for(int j = 0; j < row; j++){
                    if(Math.abs(row - j) == Math.abs(i - p[j])){
                        flag = false;
                        break;
                    }
                }
                if(flag){
                    p[row] = i;
                    line[i] = true;
                    dfs(row + 1,n,line,p);
                    line[i] = false;
                }
            }
        }
       
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值