美文网首页
平衡括号(四)——会让你怀疑自己没学过平衡括号

平衡括号(四)——会让你怀疑自己没学过平衡括号

作者: 旺叔叔 | 来源:发表于2018-11-05 17:01 被阅读0次

    LeetCode_678_ValidParenthesisString

    题目分析:

    解法一:暴力

    /**
     * 递归法暴力 遇到* 将*的三种情况都带入
     */
    public static boolean checkValidString(String s) {
        return helper(s, 0, 0);
    }
    
    public static boolean helper(String s, int start, int cnt) {
        if (cnt < 0) return false;
        for (int i = start; i < s.length(); ++i) {
            if (s.charAt(i) == '(') {
                ++cnt;
            } else if (s.charAt(i) == ')') {
                if (cnt <= 0) return false;
                --cnt;
            } else {
                return helper(s, i + 1, cnt) || helper(s, i + 1, cnt + 1) || helper(s, i + 1, cnt - 1);
            }
        }
        return cnt == 0;
    }
    

    解法二:两个栈

    /**
     * '('和*分别压栈
     * 遇到')'弹'('  '('弹完弹'*'
     * 最后如果left star 都不为空 区分*) 和 *(两个模式 如果后者模式 即存在栈顶的*在一个'('左方 false
     * 如果最终left用完 true 否则说明(右方的星号不够用
     */
    public static boolean checkValidString2(String s) {
        Stack<Integer> left = new Stack<>();
        Stack<Integer> star = new Stack<>();
        for (int i = 0; i < s.length(); ++i) {
            if (s.charAt(i) == '*') star.push(i);
            else if (s.charAt(i) == '(') left.push(i);
            else {
                if (left.empty() && star.empty()) return false;
                if (!left.empty()) left.pop();
                else star.pop();
            }
        }
        while (!left.empty() && !star.empty()) {
            if (left.peek() > star.peek()) return false;
            left.pop(); star.pop();
        }
        return left.empty();
    }
    

    解法三:来回走两遍

    /**
     * 正反两遍
     * 正时 将*当'('
     * 反时 将*当')'
     */
    public static boolean checkValidString3(String s) {
        int left = 0, right = 0, n = s.length();
        for (int i = 0; i < n; ++i) {
            if (s.charAt(i) == '(' || s.charAt(i) == '*') ++left;
            else --left;
            if (left < 0) return false;
        }
        if (left == 0) return true;
        for (int i = n - 1; i >= 0; --i) {
            if (s.charAt(i) == ')' || s.charAt(i) == '*') ++right;
            else --right;
            if (right < 0) return false;
        }
        return true;
    }
    

    解法四:左括号上下限

    /**
     * low high 分别代表遍历过程中 可存在的左括号个数的 下限 和 上限
     * 上限 < 0 false
     */
    public static boolean checkValidString4(String s) {
        int low = 0, high = 0;
        for (char c : s.toCharArray()) {
            if (c == '(') {
                ++low; ++high;
            } else if (c == ')') {
                if (low > 0) --low;
                --high;
            } else {
                if (low > 0) --low;
                ++high;
            }
            if (high < 0) return false;
        }
        return low == 0;
    }

    相关文章

      网友评论

          本文标题:平衡括号(四)——会让你怀疑自己没学过平衡括号

          本文链接:https://www.haomeiwen.com/subject/htnsxqtx.html