LeetCode51. N 皇后 (DFS , 回溯)

力扣

 

 

解题思路:

N 皇后问题:把 N 个皇后放值 N*N 的二维矩阵中,保证他们相互不能攻击: 即不在同一行,同一列,同一个斜线上 ( 撇捺 )
                                
思想: DFS + 回溯
从第一行开始放置皇后,每确定一个位置,判断是否会冲突:
是否在同一列,撇,捺, 不可能在同一行, 同一列:纵坐标相同
,对应的位置,横坐标加上纵坐标的值是相同的。
,对应的位置,横坐标减去纵坐标的值也是相同的。
当前行位置确定之后, 继续确定下一行的位置
回退,尝试当前行的其它位置
class Solution {
public:

   bool isValidPos(vector<pair<int , int>>& curRet , int row , int col)
   {
       for(const auto& pos : curRet)  //判断当前行尝试的皇后位置是否和前面几行的皇后位置有冲突
       {
           if(pos.second == col  //第i个皇后与当前这个点在同一列
           || pos.first + pos.second == row + col //第i个皇后与当前点在撇上,横坐标+纵坐标值相同
           ||  pos.first - pos.second == row - col) //第i个皇后与当前点在捺上, 横坐标-纵坐标值相同
           return false;
           
       }

       return true;
   }

   vector<vector<string>> transResult(vector<vector<pair<int ,int>>>& allRet , int n)
   {
        vector<vector<string>> allMat;
        //所有的方案
        for(vector<pair<int ,int>> curRet : allRet)
        {
            vector<string> curMat(n , string(n , '.'));
            //一种方案中的所有皇后位置
            for(pair<int ,int> pos : curRet)
            {
              curMat[pos.first][pos.second] = 'Q';
            }

            allMat.push_back(curMat);
        }

        return allMat;
   }

    void DFS(vector<vector<pair<int , int>>>& allRet , vector<pair<int , int>>& curRet , int curRow ,int n)
    {
        //如果每一行都没有冲突 , 则是一种可行的方案
        if(curRow == n)
        {
            allRet.push_back(curRet);
            return ;
        }

        //确定当前行的每一个位置是否和已确定的位置有冲突
        for(int i = 0 ; i < n; ++i)
        {
            if(isValidPos(curRet , curRow , i))
            {
                curRet.push_back(make_pair(curRow , i));
                //处理下一行
                DFS(allRet , curRet , curRow+1 , n);

                //回溯
                curRet.pop_back();
            }
        }
    }
    vector<vector<string>> solveNQueens(int n) 
    {
      vector<vector<pair<int , int>>> allRet; //按坐标位置存放所有解决方案
      vector<pair<int , int>> curRet; //存放一种解决方案中所有皇后的位置
      DFS(allRet , curRet , 0 , n);

       //把坐标转成string
      return transResult(allRet , n);
    }
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值