求解N皇后问题-基础递归版

【问题描述】在n×n的方格棋盘上,放置n个皇后,要求每个皇后不同行、不同列、不同左右对角线。如下图所示是6皇后问题的一个解。
在这里插入图片描述q[1…6]={2,4,6,1,3,5}

在这里插入图片描述
对于(i,j)位置上的皇后,是否与已放好的皇后(k,q[k])(1≤k≤i-1)有冲突呢?

在这里插入图片描述
在这里插入图片描述
  设queen(i,n)是在1~i-1行上已经放好了i-1个皇后,用于在i~n行放置n-i+1个皇后,则queen(i+1,n)表示在1~i行上已经放好了i个皇后,用于在i+1~n行放置n-i个皇后。
  queen(i+1,n)比queen(i,n)少放置一个皇后。所以queen(i+1,n)是“小问题”,queen(i,n)是“大问题”。
  在这里插入图片描述

bool place(int i,int j)		//测试(i,j)位置能否摆放皇后
{   if (i==1) return true;		//第一个皇后总是可以放置
    int k=1;
    while (k<i)			//k=1~i-1是已放置了皇后的行
    {	if ((q[k]==j) || (abs(q[k]-j)==abs(i-k)))
	    return false;
	k++;
    }
    return true;
}
void queen(int i,int n)		//放置1~i的皇后
{   if (i>n) 
	dispasolution(n);		//所有皇后放置结束
    else
    {	for (int j=1;j<=n;j++)	//在第i行上试探每一个列j
	    if (place(i,j))		//在第i行上找到一个合适位置(i,j)
	    {	q[i]=j;
		queen(i+1,n);
	    }
    }
}

51. N 皇后 - 力扣(LeetCode)

class Solution {

  int[] q;
  List<List<String>> result;

  public List<List<String>> solveNQueens(int n) {
    q = new int[n + 1];
    result=new ArrayList<>();
    queen(1,n);
    return result;
  }

  //测试(i,j)位置能否放皇后
  boolean place(int i, int j) {
    //第一个位置OK
    if (i == 1) {
      return true;
    }
    int k = 1;
    while (k < i) {
      if (j == q[k] || Math.abs(i - k) == Math.abs(j - q[k])) {
        return false;
      }
      k++;
    }
    return true;
  }

  void queen(int i, int n) {
    if (i > n) {
      dispasolution(n);  //得到一个解
      return;
    }
    for (int j = 1; j <= n; j++) {
      if (place(i, j)) {
        q[i]=j;
        queen(i + 1, n);
      }
    }
  }

  private void dispasolution(int n) {
    List<String> list = new ArrayList<>();
    for (int i = 1; i <= n; i++) {
      StringBuilder builder = new StringBuilder();
      for (int j = 1; j <= n; j++) {
        if (j == q[i]) {
          builder.append("Q");
        } else {
          builder.append(".");
        }
      }
      list.add(builder.toString());
    }
    result.add(list);
  }
}
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值