LeetCode(301):删除无效的括号 Remove Invalid Parentheses(Java)

234 篇文章 1 订阅
177 篇文章 0 订阅

2019.10.16 #程序员笔试必备# LeetCode 从零单刷个人笔记整理(持续更新)

github:https://github.com/ChopinXBP/LeetCode-Babel

括号题一般可以考虑用递归/回溯、栈等等,子串问题一般可以考虑用动态规划、滑动窗口等等。这道题结果要求输出多种组合,一般也就考虑用递归/回溯或者动态规划了。这道题的回溯思想如下:

1.先计算不匹配的左右括号数leftError、rightError。

2.开始递归回溯,返回条件是判断当前递归位置idx是否到达尾部,如果此时leftError和rightError同时为0,记录下当前结果子串。

3.递归过程分为两种情况:

4.假设当前子串需要修正:当前字符为’(‘或者’)'且对应失配数大于0时,不加入当前字符(相当于在结果中删去),向前递归。

5.假设当前子串不需要修正:将当前字符加入子串,若加入字符后子串左括号数leftCount大于右括号数rightCount则不需要修正,向前递归。


传送门:删除无效的括号

Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results.

Note: The input string may contain letters other than the parentheses ( and ).

删除最小数量的无效括号,使得输入的字符串有效,返回所有可能的结果。

说明: 输入可能包含了除 ( 和 ) 以外的字符。

示例 1:
输入: "()())()"
输出: ["()()()", "(())()"]

示例 2:
输入: "(a)())()"
输出: ["(a)()()", "(a())()"]

示例 3:
输入: ")("
输出: [""]


import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/**
 *
 * Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results.
 * Note: The input string may contain letters other than the parentheses ( and ).
 * 删除最小数量的无效括号,使得输入的字符串有效,返回所有可能的结果。
 * 说明: 输入可能包含了除 ( 和 ) 以外的字符。
 *
 */

public class RemoveInvalidParentheses {
    //回溯法
    private HashSet<String> result = new HashSet<>();
    public List<String> removeInvalidParentheses(String s) {
        //计算不匹配的左右括号数leftError、rightError
        int leftError = 0;
        int rightError = 0;
        for(int i = 0; i < s.length(); i++){
            if(s.charAt(i) == '('){
                leftError++;
            }else if(s.charAt(i) == ')'){
                if(leftError == 0){
                    rightError++;
                }else{
                    leftError--;
                }
            }
        }
        Solution(s, 0, 0, 0, leftError, rightError, new StringBuilder());
        return new ArrayList<>(result);
    }

    private void Solution(String str, int idx, int leftCount, int rightCount, int leftError, int rightError, StringBuilder expression){
        if(idx == str.length()){
            if(leftError == 0 && rightError == 0){
                result.add(expression.toString());
            }
            return;
        }
        //假设当前子串需要修正:当前字符为'('或者')'且对应失配数大于0时,不加入当前字符(相当于在结果中删去),向前递归。
        char c = str.charAt(idx);
        int length = expression.length();
        if((c == '(' && leftError > 0) || (c == ')' && rightError > 0)){
            Solution(str, idx + 1, leftCount, rightCount, leftError - (c == '(' ? 1 : 0), rightError - (c == ')' ? 1 : 0), expression);
        }

        //假设当前子串不需要修正:将当前字符加入子串,若加入字符后子串左括号数leftCount大于右括号数rightCount则不需要修正,向前递归。
        expression.append(c);
        //当前字符不为括号时,向前递归
        if(c != '(' && c != ')'){
            Solution(str, idx + 1, leftCount, rightCount, leftError, rightError, expression);
        }
        //当前字符为'('时,当前左括号数量leftCount+1,向前递归
        else if(c == '('){
            Solution(str, idx + 1, leftCount + 1, rightCount, leftError, rightError, expression);
        }
        //当前字符为')'时,当前右括号数量rightCount+1,向前递归
        else if(rightCount < leftCount){
            Solution(str, idx + 1, leftCount, rightCount + 1, leftError, rightError, expression);
        }
        expression.deleteCharAt(length);
    }
}




#Coding一小时,Copying一秒钟。留个言点个赞呗,谢谢你#

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值