关闭

Remove Invalid Parentheses--Nice

标签: 广度优先遍历
289人阅读 评论(0) 收藏 举报
分类:

参考链接

题目描述

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())()”]
“)(” -> [“”]

题目解答

解题思路

广度优先遍历的思想

代码实现

public class Solution {
    /**
     *类似广度优先遍历的思想
     */
    public List<String> removeInvalidParentheses(String s){

        List<String> ret = new ArrayList<>();
        if(s == null)
            return ret;
        if(s.length() == 0){
            ret.add(s);
            return ret;
        }


        HashSet<String> visited = new HashSet<>();
        ArrayDeque<String> queue = new ArrayDeque<>();
        queue.add(s);
        visited.add(s);
        //找到了最小的就不再继续找,只需判断queue里剩余的元素
        boolean founded = false;
        while(!queue.isEmpty()){
            String temp = queue.poll();
            if(isValid(temp)){
                ret.add(temp);
               founded = true;
            }

            //返回最小次数
            if(founded)
                continue;
            //遍历所有状态
            for(int i = 0; i < temp.length(); i++){
                if(temp.charAt(i) != ')' && temp.charAt(i) != '(')
                    continue;
                String splitStr = temp.substring(0, i) + temp.substring(i+1);
                if(!visited.contains(splitStr)){
                    visited.add(splitStr);
                    queue.add(splitStr);
                }
            }
        }
        return ret;
    }


    /**
     * 判断字符串的格式是否有效
     * 方法非常巧妙
     * 通过count来记录
     */
    public boolean isValid(String s){

        int count = 0;

        for(int i = 0; i < s.length(); i++){
            if('(' == s.charAt(i))
                count++;
            if(')' == s.charAt(i) && count-- == 0)
                return false;
        }

        return count == 0;
    }
}

深度遍历的思想
参考链接

  1. Limit max removal rmL and rmR for backtracking boundary. Otherwise it will exhaust all possible valid substrings, not shortest ones.
  2. Scan from left to right, avoiding invalid strs (on the fly) by checking num of open parens.
  3. If it’s (, either use it, or remove it.
  4. If it’s ), either use it, or remove it.
  5. Otherwise just append it.
  6. Lastly set StringBuilder to the last decision point.

In each step, make sure:

  1. idoes not exceed s.length().
  2. Max removal rmL rmR and num of open parens are non negative.
  3. De-duplicate by adding to aHashSet.
    代码实现
public class Solution {
    public List<String> removeInvalidParentheses(String s) {
        if(s == null)
            return new ArrayList<>();
        int len = s.length();
        int rmLeft = 0, rmRight = 0;
        HashSet<String> temp = new HashSet<>();
        StringBuilder sb = new StringBuilder();
        //确定最大删除数量
        for(int i = 0; i < len; i++) {
            if(s.charAt(i) == '(') {
                rmLeft++;
            }
            if(s.charAt(i) == ')') {
                if(rmLeft != 0)
                    rmLeft--;
                else
                    rmRight++;
            }
        }
        DFS(temp, s, 0, rmLeft, rmRight, 0, sb);
        return new ArrayList<>(temp);
    }

    public void DFS(HashSet<String> temp, String s, int i, int rmLeft, int rmRight, int open, StringBuilder sb) {
        if(i == s.length() && rmLeft == 0 && rmRight == 0 && open == 0) {
            temp.add(sb.toString());
            return ;
        }   
        if(i == s.length() || rmLeft < 0 || rmRight < 0 || open < 0)
            return ;
        int len = sb.length();
        if(s.charAt(i) == '(') {
            DFS(temp, s, i+1, rmLeft-1, rmRight, open, sb); // 删
            DFS(temp, s, i+1, rmLeft, rmRight, open+1, sb.append('(')); //不删
        }else if(s.charAt(i) == ')') {
            DFS(temp, s, i+1, rmLeft, rmRight-1, open, sb);
            DFS(temp, s, i+1, rmLeft, rmRight, open-1, sb.append(')'));
        }else {
            DFS(temp, s, i+1, rmLeft, rmRight, open, sb.append(s.charAt(i)));
        }
        //回溯
        sb.setLength(len);
    }
}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:41846次
    • 积分:1858
    • 等级:
    • 排名:千里之外
    • 原创:148篇
    • 转载:1篇
    • 译文:0篇
    • 评论:1条
    博客专栏
    最新评论