Parentheses总结

这篇文章总结leetcode中有关括号的问题,最简单的是判断输入的括号是否有效,例如“))”就不属于有效的括号,括号的题目无非是添加,删除,找到最长有效括号等。最长有效括号是一道DP问题,我们在DP总结中结合最长回文子串一起列出。下面列举几个基本的题目。

[b]1,Valid Parentheses[/b]
给定一个字符串序列,它包含'(', ')', '{', '}', '[' , ']',判断字符串是否是有效括号组成的。
例如:"()" 和 "()[]{}" 是有效字符串;而 "(]" 和 "([)]" 就不是合法字符串。

我们用堆栈解决这道题,从第一个字符开始遍历,遇到‘(’ , '{' 或‘{’时,我们就把它压入到堆栈中,如果遇到‘)' , ']' 和‘}’时我们将字符出栈,并且与当前字符比较,如果匹配就继续查找,如果不匹配返回false。在遍历完之后,我们要检查堆栈是否为空,如果不为空,也返回false。
例如“((())”就会导致遍历结束后,栈中还有一个字符‘(’,而它是无效的字符串。代码如下:


public class Solution {
public boolean isValid(String s) {
Stack<Character> stack = new Stack<Character>();
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if(c == '[' || c == '(' || c == '{') {
stack.push(c);
} else {
if(stack.isEmpty())
return false;
char cs = stack.pop();
if((c == ')' && cs == '(') || (c == ']' && cs == '[') || (c == '}' && cs == '{'))
continue;
else
return false;
}
}
if(!stack.isEmpty())
return false;
return true;
}
}


[b]2,Generate Parentheses[/b]
给定n对括号,列出所有可能的有效组合。
例如:n = 3
输出 :"((()))", "(()())", "(())()", "()(())", "()()()"

看到组合问题我们就想到用回溯法,回溯的条件是字符串的长度为2n时,我们就把它记录下来,然后回溯找其它的答案。当查找的时候,我们设定两个变量left和right,分别代表左括号的数量和右括号的数量,当左括号不为零时,我们可以继续添加左括号;而对于右括号,我们要保证再往下查找的时,右括号的数量大于左括号的数量(right > left), 否则就会生成错误结果。
代码如下:

public class Solution {
public List<String> generateParenthesis(int n) {
LinkedList<String> list = new LinkedList<String>();
int left = n;
int right = n;
String result = "";
generateParent(n, left, right, result, list);
return list;
}

public void generateParent(int n, int left, int right, String result, LinkedList<String> list) {
if(result.length() == 2 * n) {
list.add(result);
}
if(left > 0) generateParent(n, left - 1, right, result + "(", list);
if(right > left) generateParent(n, left, right - 1, result + ")", list);
}
}


[b]3,Different Ways to Add Parentheses[/b]
给定一个字符串,字符串由数字和操作符组成,通过添加不同的括号列出所有可能的计算结果。
例如:输入:"2*3-4*5"
输出:[-34, -14, -10, -10, 10]
结果是由以下的方式计算出来的:
(2*(3-(4*5))) = -34
((2*3)-(4*5)) = -14
((2*(3-4))*5) = -10
(2*((3-4)*5)) = -10
(((2*3)-4)*5) = 10

这道题我们用递归来解决,遍历字符串,当遇到操作符号时,我们就分别递归当前操作符的左边部分和右边部分,最终得到结果。代码如下:

public class Solution {
public List<Integer> diffWaysToCompute(String input) {
List<Integer> list = new LinkedList<Integer>();
if(!input.contains("+") && !input.contains("-") && !input.contains("*")) {
list.add(Integer.valueOf(input));
return list;
}
for(int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if(c == '+' || c == '*' || c == '-') {
List<Integer> leftlist = diffWaysToCompute(input.substring(0, i));
List<Integer> rightlist = diffWaysToCompute(input.substring(i + 1, input.length()));
for(int leftvalue : leftlist)
for(int rightvalue : rightlist) {
switch (c) {
case '+':
list.add(leftvalue + rightvalue);
break;
case '-':
list.add(leftvalue - rightvalue);
break;
case '*':
list.add(leftvalue * rightvalue);
break;
}
}
}
}
return list;
}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值