LeetCode 题解(285) :Remove Invalid Parentheses

题目:

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 ).

Examples:

"()())()" -> ["()()()", "(())()"]
"(a)())()" -> ["(a)()()", "(a())()"]
")(" -> [""]

题解:

几个关键步骤:

1. 预处理,删除头部的")"和尾部的“(”。

2. 每次删除一个character,需要判断删除后是否mis-match数减少或为0,如果减少加入candidate中进行进一步处理,如果为0则表示找到答案。需要处理完当前queue中的余下candidates,因为结果可能不止一个。

3. 用一个set可以避免处理重复元素。

Java版 14ms:

public class Solution {
    
    public List<String> removeInvalidParentheses(String s) {
        Queue<String> candidates = new LinkedList<String>();
        List<String> results = new ArrayList<String>();
        s = preprocessing(s);
        if(s.equals("")) {
            results.add("");
            return results;
        }
        
        //The overall idea is just to remove one character each time, if after removing, the number of mismatch is going down,
        //then put this new expression into a new queue. If after removing, the new expression is a valid expression, then we
        //find the result with the minimum removing steps. After processsing the remainder elements in the current queue, we
        //can return the results.
        candidates.add(s);
        while(!candidates.isEmpty()) {
            Queue<String> candidates2 = new LinkedList<String>();
            //Using a set to remove the duplicates will expediate the process dramatically.
            Set<String> candidateSet = new HashSet<>();
            boolean valid = false;
            while(!candidates.isEmpty()) {
                String cur = candidates.poll();
                if(findNumMisMatch(cur) == 0) {
                    results.add(cur);
                    if(valid == false)
                        valid = true;
                } else {
                    for(int i = 0; i < cur.length(); i++) {
                        if(i != 0 && cur.charAt(i) == cur.charAt(i - 1))
                            continue;
                        StringBuilder newSB = new StringBuilder(cur.substring(0, i));
                        if(i != cur.length() - 1)
                            newSB.append(cur.substring(i+1));
                        String newS = newSB.toString();
                        if(!candidateSet.contains(newS) && findNumMisMatch(newS) < findNumMisMatch(cur)) {
                            candidateSet.add(newS);
                            candidates2.add(newS);
                        }
                    }
                }
            }
            if(valid == true)
                return results;
            candidates.addAll(candidates2);
        }
        return results;
    }

    //This function is used to evaluate whether an expression is valid. If it returns 0, the expression is valid.
    //It can also give the number of elements need to be removed to make a valid expression.
    public int findNumMisMatch(String s) {
        int numLeft = 0, numRight = 0;
        for(int i = 0; i < s.length(); i++) {
            if(s.charAt(i) == '(') {
                numLeft++;
            } else if(s.charAt(i) == ')') {
                if(numLeft == 0) {
                    numRight++;
                } else {
                    numLeft--;
                }
            }
        }
        return numLeft + numRight;
    }
    
    //Remove the trailing ")"s in the front and the tailing "("s, because these parentheses must be removed to make a valid 
    //expression. 
    public String preprocessing(String s) {
        StringBuilder sb = new StringBuilder();
        boolean leftAppear = false;
        int i = 0;
        while(!leftAppear && i < s.length()) {
            if(s.charAt(i) == '(') {
                leftAppear = true;
                sb.append(s.charAt(i));
            }
            else if(s.charAt(i) == ')') {
                i++;
                continue;
            }
            else {
                sb.append(s.charAt(i));
            }
            i++;
        }
        s = sb.append(s.substring(i)).toString();
        sb = new StringBuilder();
        boolean rightAppear = false;
        i = s.length() - 1;
        while(!rightAppear && i >= 0) {
            if(s.charAt(i) == ')') {
                rightAppear = true;
                sb.insert(0, s.charAt(i));
            }
            else if(s.charAt(i) == '(') {
                i--;
                continue;
            }
            else {
                sb.insert(0, s.charAt(i));
            }
            i--;
        }
        return sb.insert(0, s.substring(0, i+1)).toString();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值