[LeetCode 52] N皇后 II

题目描述

在这里插入图片描述
示例:

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

["…Q.", // 解法 2
“Q…”,
“…Q”,
“.Q…”]
]

题目分析

N皇后 II和LeetCode 51其实是一摸一样的题,不过这道题就是把回溯做到底了而已,相比之下比上一题更简单了。

源码

class Solution {
public int totalNQueens(int n) {
    boolean[] col=new boolean[n];
    boolean[] main_diag=new boolean[2*n];
    boolean[] anti_diag=new boolean[2*n];
    return dfs(col,main_diag,anti_diag,n,0);
    //回溯
}
public int dfs(boolean[] col,boolean[] main_diag,boolean[] anti_diag,int n,int row){
    int res=0;
    if(row==n){
        return 1;
    }
    //回溯结束条件,就是行数遍历完了
    for(int i=0;i<n;i++){
        if(!col[i]&&!main_diag[i+row]&&!anti_diag[row-i+n]){
            col[i]=true;
            main_diag[i+row]=true;
            anti_diag[row-i+n]=true;
            res+=dfs(col,main_diag,anti_diag,n,row+1);
            //递归,能符合一次题意就递加一次
            //回溯
            col[i]=false;
            main_diag[i+row]=false;
            anti_diag[row-i+n]=false;
        }
    }
    return res;
}
}

改进

上面其实已经很方便了,但是还是用了三个数组,感觉太多了,应该找个办法就用一个数组queen,其他的行列对角线我都用索引来表示吧。虽然这样是降低了储存空间,但是时间复杂度却提高了。因此不能算是改进,只能算方法二吧。

改进代码

class Solution {
public int count=0;
public int totalNQueens(int n) {
   boolean[][] q = new boolean[n][n];
   Queen(0,n,q);
   return count;
}
public void Queen(int j,int n,boolean[][] Q){
   int i,k;
   if (j == n){
       count++;
   }
   for (i=0;i<n;i++){
       if (isCorrect(i,j,n,Q)){
           Q[i][j] = true;
           Queen(j+1,n,Q);
           Q[i][j] = false;
       }
   }
} 
public boolean isCorrect(int i,int j,int n,boolean[][] Q){
   int s,t;
   //判断行
   for (s=i,t=0;t<n;t++)
       if (Q[s][t] && t != j)
           return false;
   //判断列
   for (s=0,t=j;s<n;s++)
       if (Q[s][t] && s != i)
           return false;
   //判断左上方
   for (s=i-1,t=j-1;s >= 0 & t >= 0;s--,t--)
       if (Q[s][t])
           return false;
   //判断左下方
   for (s=i+1,t=j-1;s<n && t>=0;s++,t--)
       if (Q[s][t])
           return false;
   //判断右上方
   for (s=i-1,t=j+1;s>=0 && t<n;s--,t++)
       if (Q[s][t])
           return false;
   //判断右下方
   for (s=i+1,t=j+1;s<n && t<n;s++,t++)
       if (Q[s][t])
           return false;
   return true;
}
}

分析

时间复杂度为O(n*m)

难点

只要在上一题的理解上再进行完整的回溯就可以啦。重点还是回溯算法啦。

小结

复习了一次回溯算法。

[1]https://leetcode-cn.com/problems/n-queens-ii/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值