两道括号相关的leetcode题22_301

22. Generate Parentheses

写出n对括号的所有合法形式。

For example, given n = 3, a solution set is:
[ “((()))”, “(()())”, “(())()”, “()(())”, “()()()” ]

回溯求解,不过要单独统计左括号和右括号个数,同时加入左括号和加入右括号是平行的关系,不是if else,这样在回溯时才能加入右括号:

public List<String> generateParenthesis(int n) {
    help(n, 0, new StringBuffer(""), 0, 0);
    return res;
}

List<String> res = new ArrayList<>();
public void help(int n, int k, StringBuffer str, int open, int close) {
    if (k == n*2) {
        res.add(str.toString());
    }

    if (open < n) {
        str.append('(');
        help(n, k+1, str, open+1, close);
        str.deleteCharAt(k);
    }
    //非if else
    if (close < n && open > close) {
        str.append(')');
        help(n, k+1, str, open, close+1);
        str.deleteCharAt(k);
    }
}

301. Remove Invalid Parentheses

给一个不合法的包含括号的字符串,去掉最小的括号数量使其合法,有多少种合法的字符串形式。字符串中可能包含非括号字符,不用管它。

Input: “()())()”
Output: ["()()()", “(())()”]

还是有点难的,使用dfs:

  1. 遍历字符串,当遇到不合法的括号时,把从上个修改后的元素到这个元素之间的这一段子字符串再遍历一遍,是为了进行修改获得所有的正确子字符串,之后用这个正确子字符串加上后面的子字符串继续遍历
  2. 中间进行了return是为了处理了不合法的括号后直接跳出这个循环,不然结果就会带上这个不合法的括号
  3. 如果是左括号比右括号多的情况,把字符串反转,并且左右括号定义反转,这样就相当于转换成了右括号比左括号多了,重用了代码
public List<String> removeInvalidParentheses(String s) {
    help(s, 0, 0, '(', ')');
    return res;
}

List<String> res = new ArrayList<>();
public void help(String s, int kStart, int iStart, char leftPar, char rightPar) {
    int open = 0, close = 0;
    for (int k = kStart; k < s.length(); k++) {
        if (s.charAt(k) == leftPar) open++;
        if (s.charAt(k) == rightPar) close++;
        if (open >= close) continue;

        for (int i = iStart; i <= k; i++) {
            if (s.charAt(i) == rightPar && (i == iStart || s.charAt(i-1) != rightPar))
                help(s.substring(0, i) + s.substring(i+1, s.length()), k, i, leftPar, rightPar);
        }
        //这里返回是为了在去掉不合法括号后能跳过这次循环,如果不跳过下次循环就会带上不合法的括号
        return;
    }

    String reverse = new StringBuffer(s).reverse().toString();
    if (leftPar == '(')
        help(reverse, 0, 0, rightPar, leftPar);
    else
        res.add(reverse);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值