力扣|51.N皇后、37.解数独

51.N皇后

51. N 皇后 - 力扣(LeetCode)

题目解析:这道题是回溯算法中的难题,如果我们按照之前解回溯算法题去树形结构会发现与之前那些收集子集或集合不一样的点在于,我们需要用二维数组去构建一个棋盘,一行一行的去遍历,遍历列的时候就经过递归去遍历。最重要的是去重的过程,要进行列去重,45度去重及135度去重,因为是通过行遍历所以行不用去重。

具体代码如下:

class Solution {
private:
    vector<vector<string>> result;
    void backTracking(int n,int row,vector<string>& chessbroad){
        //n代表棋盘大小,row记录当前遍历到哪一层
        if(n == row){
            result.push_back(chessbroad);
            return;
        }
        for(int col = 0;col < n;col++){//列控制外层循环,在确定的一行内遍历,由列控制
            if(isvalid(row,col,chessbroad,n)){
                chessbroad[row][col] = 'Q';//放置皇后
                //行控制递归
                backTracking(n,row + 1,chessbroad);//从当前行的下一行进行遍历
                chessbroad[row][col] = '.';//撤销皇后
            }
        }
    }
    bool isvalid(int row,int col,vector<string>& chessbroad,int n){
        //列去重
        for(int i = 0;i < row;i++){
            if(chessbroad[i][col] == 'Q'){
                return false;
            }
        }
        //45度去重
        for(int i = row - 1,j = col - 1;i >= 0&&j >= 0;i--,j--){
            if(chessbroad[i][j] == 'Q'){
                return false;
            }
        }
        //135度去重
        for(int i = row - 1,j = col + 1;i >= 0&&j < n;i--,j++){
            if(chessbroad[i][j] == 'Q'){
                return false;
            }
        }
        return true;
    }
public:
    vector<vector<string>> solveNQueens(int n) {
       result.clear();
       std::vector<std::string> chessbroad(n,std::string(n,'.'));//大小为n的字符串本身就是一个大小为n的字符数组。
       backTracking(n,0,chessbroad);
       return result;
    }
};

37.解数独 

37. 解数独 - 力扣(LeetCode)

 

解题思路:

本题与n皇后类似,用递归回溯的方法去匹配看此空填1-9中那个数满足要求。

具体代码如下:

class Solution {
private:
    bool backTracking(vector<vector<char>>& board){//因为只要确定最后得出的数独是否满足要求,所以用bool
        for(int i = 0;i < board.size();i++){
            for(int j = 0;j < board.size();j++){
                if(board[i][j] == '.') {
                    //如果此空为空就看1-9的数字是否能匹配上
                    for(char k = '1';k <= '9';k++){
                        if(isVaild(i,j,k,board)){
                            board[i][j] = k;
                            bool result = backTracking(board);
                            if(result) return true;
                            board[i][j] = '.';
                        }
                    }
                    return false;//如果九个数都不符合就返回false
                }
            }
        }
        return true;//遍历完没有返回false,就说明找到了最合适的结果
    }
    bool isVaild(int row,int col,char val,vector<vector<char>>& board){
        //判断行是否有重复
        for(int i = 0;i < board.size();i++){
            if(board[row][i] == val){
                return false;
            }
        }
        //判断列是否有重复
        for(int j = 0;j < board.size();j++){
            if(board[j][col] == val){
                return false;
            }
        }
        //判断九宫格中是否有重复
        int startrow = (row / 3) * 3;
        int startcol = (col / 3) * 3;
        for(int i = startrow;i < startrow + 3;i++){
            for(int j = startcol;j < startcol + 3;j++){
                if(board[i][j] == val){
                    return false;
                }
            }
        }
        return true;
    }
public:
    void solveSudoku(vector<vector<char>>& board) {
        backTracking(board);
    }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值