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

2018-11-05  本文已影响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;
}
上一篇下一篇

猜你喜欢

热点阅读