N-Queens And N-Queens II [LeetCode] + Generate Parentheses[LeetCode] + 回溯法

N-Queens And N-Queens II [LeetCode] + Generate Parentheses[LeetCode] + 回溯法

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

回溯法

百度百科:回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步又一次选择,这样的走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

在包括问题的全部解的解空间树中,依照深度优先搜索的策略,从根结点出发深度探索解空间树。当探索到某一结点时,要先推断该结点是否包括问题的解,假设包括,就从该结点出发继续探索下去,假设该结点不包括问题的解,则逐层向其祖先结点回溯。(事实上回溯法就是对隐式图的深度优先搜索算法)。 若用回溯法求问题的全部解时,要回溯到根,且根结点的全部可行的子树都要已被搜索遍才结束。 而若使用回溯法求任一个解时,仅仅要搜索到问题的一个解就能够结束。


做完以下几题,应该会对回溯法的掌握有非常大帮助
N-Queens http://oj.leetcode.com/problems/n-queens/
N-Queens II   http://oj.leetcode.com/problems/n-queens-ii/
Generate Parentheses http://oj.leetcode.com/problems/generate-parentheses/


N-Queens

Follow up for N-Queens problem.

Now, instead outputting board configurations, return the total number of distinct solutions.

N-Queens And N-Queens II [LeetCode] + Generate Parentheses[LeetCode] + 回溯法

Given an integer n, return all distinct solutions to the n-queens puzzle.

Each solution contains a distinct board configuration of the n-queens’ placement, where 'Q' and '.' both indicate a queen and an empty space respectively.

For example,
There exist two distinct solutions to the 4-queens puzzle:

[
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]
]

经典的八皇后问题的扩展,利用回溯法,

(1)从第一列開始试探性放入一枚皇后

(2)推断放入后棋盘是否安全,调用checkSafe()推断

(3)若checkSafe()返回true,继续放下一列,若返回false,回溯到上一列,又一次寻找安全位置

(4)遍历全然部位置,得到结果

class Solution {public:    vector<vector<string> > solveNQueens(int n) {        int *posArray = new int[n];        int count = 0;        vector< vector<string> > ret;          placeQueue(0, n, count, posArray, ret);        return ret;    }        //检查棋盘安全性    bool checkSafe(int row, int *posArray){        for(int i=0; i < row; ++i){            int diff = abs(posArray[i] - posArray[row]);                  if (diff == 0 || diff == row - i) {                       return false;              }          }        return true;    }        //放置皇后    void placeQueue(int row, int n, int &count, int *posArray, vector< vector<string> > &ret){        if(n == row){            count++;            vector<string> tmpRet;              for(int i = 0; i < row; i++){                  string str(n, '.');                  str[posArray[i]] = 'Q';                  tmpRet.push_back(str);              }              ret.push_back(tmpRet);            return;        }        //从第一列開始试探        for(int col=0; col<n; ++col){            posArray[row] = col;            if(checkSafe(row, posArray)){                 //若安全,放置下一个皇后                placeQueue(row+1, n, count, posArray, ret);            }        }    }};

N-Queens II

 

Follow up for N-Queens problem.

Now, instead outputting board configurations, return the total number of distinct solutions.

仅仅需计算个数count即可,略微改动

class Solution {public:    int totalNQueens(int n) {        int *posArray = new int[n];        int count = 0;        vector< vector<string> > ret;          placeQueue(0, n, count, posArray, ret);        return count;    }         //检查棋盘安全性    bool checkSafe(int row, int *posArray){        for(int i=0; i < row; ++i){            int diff = abs(posArray[i] - posArray[row]);                  if (diff == 0 || diff == row - i) {                       return false;              }          }        return true;    }        //放置皇后    void placeQueue(int row, int n, int &count, int *posArray, vector< vector<string> > &ret){        if(n == row){            count++;            return;        }        //从第一列開始试探        for(int col=0; col<n; ++col){            posArray[row] = col;            if(checkSafe(row, posArray)){                //若安全,放置下一个皇后                placeQueue(row+1, n, count, posArray, ret);            }        }    }};

Generate Parentheses

刚做完N-QUEUE问题,受之影响,此问题也使用回溯法解决,代码看上去多了非常多

class Solution {
public:
    vector<string> generateParenthesis(int n) {
       vector<string> vec; 
       int count = 0;
       int *colArr = new int[2*n];
       generate(2*n, count, 0, colArr, vec);
       delete[] colArr;
       return vec;
    }
    
    //放置括弧
    void generate(int n,int &count, int col, int *colArr, vector<string> &vec){
        if(col == n){
            ++count;
            string temp(n,'(');
            for(int i = 0;i< n;++i){
                if(colArr[i] == 1)
                    temp[i] = ')';
            }
            vec.push_back(temp);
            return;
        }
        for(int i=0; i<2;++i){
            colArr[col] = i;
            if(checkSafe(col, colArr, n)){
                //放置下一个括弧
                generate(n, count, col+1, colArr, vec);
            }
        }
    }
    
    //检查安全性
    bool checkSafe(int col, int *colArr, int n){
		int total = n/2;
        if(colArr[0] == 1) return false;
        int left = 0, right = 0;
        for(int i = 0; i<=col; ++i){
            if(colArr[i] == 0 )
                ++left;
            else 
                ++right;
        }
        if(right > left || left > total || right > total)
            return false;
        else
            return true;
    }
};

google了下,http://blog.csdn.net/pickless/article/details/9141935 代码简洁非常多,供參考

class Solution {
public:
    vector<string> generateParenthesis(int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        vector<string> ans;
        getAns(n, 0, 0, "", ans);
        return ans;
    }

private:
    void getAns(int n, int pos, int neg, string temp, vector<string> &ans) {
        if (pos < neg) {
            return;
        }
        if (pos + neg == 2 * n) {
            if (pos == neg) {
                ans.push_back(temp);
            }
            return;
        }
        getAns(n, pos + 1, neg, temp + '(', ans);
        getAns(n, pos, neg + 1, temp + ')', ans);
    }
};

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/118294.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 单细胞测序流程(单细胞rna测序)

    系列文章目录文章目录 单细胞测序流程(一)简介与数据下载 单细胞测序流程(二)数据整理 单细胞测序流程(三)质控和数据过滤——Seurat包分析,小提琴图和基因离差散点图 单细胞测序流程(四)主成分分析——PCA 单细胞测序流程(五)t-sne聚类分析和寻找marker基因 单细胞测序流程(六)单细胞的细胞类型的注释 单细胞测序流程(七)单细胞的细胞类型轨迹分析单细胞测序流程(八)单细胞的marker基因转化和​GO富集分析 单细胞测序流程(九)单细胞的GO圈图

  • Linux vim退出命令(保存与不保存)「建议收藏」

    Linux vim退出命令(保存与不保存)「建议收藏」按ESC键跳到命令模式,然后输入::w-保存文件,不退出vim:wfile-将修改另外保存到file中,不退出vim:w!-强制保存,不退出vim:wq-保存文件,退出vim:wq!-强制保存文件,退出vim:q-不保存文件,退出vim:q!-不保存文件,强制退出vim:e!-放弃所有修改,从上次保存文件开始再编辑…

  • ctf-web:关于文件上传漏洞的深入研究[通俗易懂]

    ctf-web:关于文件上传漏洞的深入研究[通俗易懂]上次我们研究了关于文件上传的漏洞,这次我们研究的内容属于上节课的补充内容,关于文件上传的绕过与防御.怎么说呢,算是一种锻炼吧.因为下个月有个awd的比赛,因此最近会经常发一些关于web的内容.其实我还是挺慌的,因为以前参加的都是ctf线上赛,而且我做的都是逆向这个方面的,然而这次突然来了个web,搞得我有点懵.web也是最近才开始研究的,所以写的可能不尽人意,希望各位大佬看看就好,不喜勿喷.一.实验环境我们这次的实验依然用的是上次的网站和phpstudy.我发在了下面.1.upload-f.

  • C语言中的所有运算符用法及总结[通俗易懂]

    C语言中的所有运算符用法及总结[通俗易懂]简单明了的讲解各种运算符的用法及实例

  • Shortcuts(快捷方式) Android7

    Shortcuts(快捷方式) Android7

  • 数据库怎么创建学生表_设计数据库,创建数据库和数据表

    数据库怎么创建学生表_设计数据库,创建数据库和数据表知识点:数据库表的相关概念、创建数据库表的方法、设计数据库表、向数据库表中插入数据、建立不同数据库表之间的关系、删除数据库表。1、数据表相关的一些概念1.1数据库里的数据是如何保存的?数据库到底是怎么存储数据的?比如要把学生信息存储到数据库里,能把学生塞进数据库吗?肯定是把学生的数据信息抽象出来,把一些重要信息以文字或数字的形式保存到数据库中去。…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号