lintcode刷题--生成括号
2017-10-21 16:42
225 查看
题目描述:给定 n 对括号,请写一个函数以将其生成新的括号组合,并返回所有组合结果。
样例:
给定 n = 3, 可生成的组合如下: "((()))", "(()())", "(())()", "()(())", "()()()"
这道题就有些难度了。
想一想这种生成括号的规则,其实隐含了一条信息:那就是始终左括号的数量要大于或等于右括号的数量。也就是说,剩余的左括号的数量要始终小于等于右括号。左括号只要有,就可以打印;而只有当剩余的右括号数量比左括号大时,才能打印右括号。为了方便理解,我现在假设n = 2,那么根据刚才我说的隐含信息,逻辑应该是这样的:
1. 肯定要先取一个左括号,此时左括号剩余的数量变为1,右括号剩余数量还是2
2. 第二位取左括号也行,取右括号也行。如果取左括号,那么此时右括号剩余数量为2,左括号剩余数量为0,长成了这个样子"((";如果取右括号,左右剩余数量都是1,长成这个样子"()"
3. 第三位,如果剩余左括号没了,就只能跟进右括号了,连续两个,最终变成"(())";而如果现在是"()"的,那么要先左后右,最终变成"()()".
发现,每一步都有两种选择:左或者右,当然不一定都可行,如果可行,那么往后继续,不可行,终止。
这是什么,二叉树。对于n = 2的情况,他的二叉树应该是这样的:
--------------------------------------------------------------python版本----------------------------
这棵二叉树表达的东西其实跟我刚才说的是一样的,而我们所要的结果就是这棵二叉树遍历所有路径的结果。由此,不妨先来回忆一下之前“二叉树的所有路径”这道题目(详见:点击打开链接)可以仿照这个方法来解决我们当前的问题。所不同的是,这里我们没有一棵已经给出的二叉树,但是,此处,我们相当于知道了这棵二叉树的左右节点是否为空的条件(就是一开始的隐含信息,左括号要始终大于等于右括号,也就是说剩余的左括号要始终小于等于剩余的右括号),以及不为空时,节点的值(左括号为"(",右括号为")")。
那么可以尝试给出代码了:
[python] view plain copy
class Solution:
# @param {int} n n pairs
# @return {string[]} All combinations of well-formed parentheses
def generateParenthesis(self, n):
result = []
path = ""
self.helper(n, n, path, result)
return result
# left和right为判断节点是否存在提供依据
def helper(self, left, right, path, result):
# 相当于节点为空,也就是深搜不能再深入了
if left == right == 0:
result.append(path)
# 相当于左节点存在
if left > 0:
self.helper(left - 1, right, path + "(", result)
# 相当于右节点存在
if right > left:
self.helper(left, right - 1, path + ")", result)
# Write your code here
----------------------------------------------------------java版本------------------------------------------
Given
搜索每一种可能的结果,可以使用BFS或者DFS。BFS可是考虑使用队列。但这道题更适合用DFS求解。注意helper函数接收left和right变量,作为左括号和右括号剩余数量。注意当left小于right时,属于异常情况,括号不能完整匹配,所以此时直接
ee15
返回即可。另外通过变量res储存结果。
[java] view
plain copy
public class Solution {
/**
* @param n n pairs
* @return All combinations of well-formed parentheses
*/
public ArrayList<String> generateParenthesis(int n) {
// DFS
ArrayList<String> res = new ArrayList<String>();
helper(n, n, n, "", res);
return res;
}
void helper(int n, int left, int right, String str, ArrayList<String> res) {
if(left > right) return;
if (left == 0 && right == 0) {
res.add(str);
return;
} else if (left == 0 && right != 0) {
while(right-- > 0) str += ")";
res.add(str);
return;
} else if (left != 0 && right == 0) {
return;
} else{
helper(n, left - 1, right, str + "(", res);
helper(n, left, right - 1, str + ")", res);
return;
}
}
}
----------------------------------------------------------------------------------------------------------java版本-------------------------------------------------------------------------------------------------------------
样例:
给定 n = 3, 可生成的组合如下: "((()))", "(()())", "(())()", "()(())", "()()()"
这道题就有些难度了。
想一想这种生成括号的规则,其实隐含了一条信息:那就是始终左括号的数量要大于或等于右括号的数量。也就是说,剩余的左括号的数量要始终小于等于右括号。左括号只要有,就可以打印;而只有当剩余的右括号数量比左括号大时,才能打印右括号。为了方便理解,我现在假设n = 2,那么根据刚才我说的隐含信息,逻辑应该是这样的:
1. 肯定要先取一个左括号,此时左括号剩余的数量变为1,右括号剩余数量还是2
2. 第二位取左括号也行,取右括号也行。如果取左括号,那么此时右括号剩余数量为2,左括号剩余数量为0,长成了这个样子"((";如果取右括号,左右剩余数量都是1,长成这个样子"()"
3. 第三位,如果剩余左括号没了,就只能跟进右括号了,连续两个,最终变成"(())";而如果现在是"()"的,那么要先左后右,最终变成"()()".
发现,每一步都有两种选择:左或者右,当然不一定都可行,如果可行,那么往后继续,不可行,终止。
这是什么,二叉树。对于n = 2的情况,他的二叉树应该是这样的:
--------------------------------------------------------------python版本----------------------------
这棵二叉树表达的东西其实跟我刚才说的是一样的,而我们所要的结果就是这棵二叉树遍历所有路径的结果。由此,不妨先来回忆一下之前“二叉树的所有路径”这道题目(详见:点击打开链接)可以仿照这个方法来解决我们当前的问题。所不同的是,这里我们没有一棵已经给出的二叉树,但是,此处,我们相当于知道了这棵二叉树的左右节点是否为空的条件(就是一开始的隐含信息,左括号要始终大于等于右括号,也就是说剩余的左括号要始终小于等于剩余的右括号),以及不为空时,节点的值(左括号为"(",右括号为")")。
那么可以尝试给出代码了:
[python] view plain copy
class Solution:
# @param {int} n n pairs
# @return {string[]} All combinations of well-formed parentheses
def generateParenthesis(self, n):
result = []
path = ""
self.helper(n, n, path, result)
return result
# left和right为判断节点是否存在提供依据
def helper(self, left, right, path, result):
# 相当于节点为空,也就是深搜不能再深入了
if left == right == 0:
result.append(path)
# 相当于左节点存在
if left > 0:
self.helper(left - 1, right, path + "(", result)
# 相当于右节点存在
if right > left:
self.helper(left, right - 1, path + ")", result)
# Write your code here
----------------------------------------------------------java版本------------------------------------------
Given
n = 3, a solution set is:
"((()))", "(()())", "(())()", "()(())", "()()()"
搜索每一种可能的结果,可以使用BFS或者DFS。BFS可是考虑使用队列。但这道题更适合用DFS求解。注意helper函数接收left和right变量,作为左括号和右括号剩余数量。注意当left小于right时,属于异常情况,括号不能完整匹配,所以此时直接
ee15
返回即可。另外通过变量res储存结果。
[java] view
plain copy
public class Solution {
/**
* @param n n pairs
* @return All combinations of well-formed parentheses
*/
public ArrayList<String> generateParenthesis(int n) {
// DFS
ArrayList<String> res = new ArrayList<String>();
helper(n, n, n, "", res);
return res;
}
void helper(int n, int left, int right, String str, ArrayList<String> res) {
if(left > right) return;
if (left == 0 && right == 0) {
res.add(str);
return;
} else if (left == 0 && right != 0) {
while(right-- > 0) str += ")";
res.add(str);
return;
} else if (left != 0 && right == 0) {
return;
} else{
helper(n, left - 1, right, str + "(", res);
helper(n, left, right - 1, str + ")", res);
return;
}
}
}
----------------------------------------------------------------------------------------------------------java版本-------------------------------------------------------------------------------------------------------------
相关文章推荐
- LintCode : 生成括号
- lintcode,生成括号
- LintCode:生成括号
- lintcode--生成括号
- LintCode-生成括号
- LintCode_有效的括号序列
- Lint-code-有效的括号序列
- Leet Code 22 Generate Parentheses - 生成括号 - Java
- lintcode--有效的括号序列
- lintcode&九章算法——Google面试题 | 有效括号字符串 ? 待解决
- Code 生成括号
- lintcode: 有效的括号序列
- LintCode:有效的括号序列
- lintcode 容易题:Hash Function 哈希函数
- QRCode.js:使用 JavaScript 生成二维码
- Lintcode 跳跃游戏
- lintcode ----落单的数
- LintCode:打劫房屋 II
- LintCode 生成括号
- ThoughtWorks.QRCode生成二维码