Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

回溯算法 #24

Open
wengjq opened this issue Aug 27, 2018 · 0 comments
Open

回溯算法 #24

wengjq opened this issue Aug 27, 2018 · 0 comments

Comments

@wengjq
Copy link
Owner

wengjq commented Aug 27, 2018

概念

具有限界条件的 DFS (Depth first search,深度优先搜索)算法称为回溯算法。

例子

LeetCode 的第 22 题

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

For example, given n = 3, a solution set is:

[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]

题目目的是给你一个数 n 写出来所有中可能的括号集合。

本题采用的回溯的解题思想:所谓(回溯)Backtracking 都是这样的思路:在当前局面下,你有若干种选择。那么尝试每一种选择。如果已经发现某种选择肯定不行(因为违反了某些限定条件),就返回;如果某种选择试到最后发现是正确解,就将其加入解集。

对于这道题,有以下的限制条件:

1、如果左括号已经用完了,则不能再加左括号
2、如果已经出现的右括号和左括号一样多,则不能再加右括号了。因为那样的话新加入的右括号一定无法匹配。

结束条件是:
左右括号都已经用完。

因此,把上面的思路写一下伪代码:

if (左右括号都已用完) {
  加入解集,返回
}
// 否则开始情况
if (还有左括号可以用) {
  加一个左括号,继续递归
}
if (右括号小于左括号) {
  加一个右括号,继续递归
}

具体实现:

/**
 * @param {number} n
 * @return {string[]}
 */
 var generateParenthesis = function (n) {
    var ans = [];
    
    dfs(ans, '', 0, 0, n);
    
    return ans;
};

function dfs(ans, str, left, right, n) {
    if (left === n && right === n) ans.push(str);
    
    if (left < n) {
        dfs(ans, str + '(', left + 1, right, n);
    }
    
    if (right < left) {
        dfs(ans, str + ')', left, right + 1, n);
    }
}

console.log(generateParenthesis(3)); //  ["((()))", "(()())", "(())()", "()(())", "()()()"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant