Valid Parenthesis String with Wildcards

medium Strings

Problem

A string has only the characters (, ) and *. The star * can be an open bracket, a close bracket, or nothing (empty). Print true if the stars can be chosen so that all brackets are matched in the right order, otherwise false.

Constraints

  • 1 <= length <= 100

Examples

Input

(*)

Output

true

Input

(*))

Output

true

Input

)(

Output

false

Solutions

Best approachTime O(n)Space O(1)

Instead of trying every choice for the stars, track the range of possible open-bracket counts. The string is valid if the range never loses its upper part and can end at zero.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Can the stars fix the brackets?
 * Input   : One string.
 * Output  : true or false.
 * Approach: Range of open brackets
 * Time    : O(n)
 * Space   : O(1)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
    // This method solves the task. It receives the input and returns the answer.
    static boolean solve(String s) {
        // Step 1: Keep the smallest and the largest possible number of open brackets at this point.
        int low = 0;
        int high = 0;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            // Step 2: An open bracket adds one to both. A close bracket removes one from both.
            // Step 3: A star may be open, close or empty, so low goes down and high goes up.
            if (c == '(') {
                low++;
                high++;
            } else if (c == ')') {
                low--;
                high--;
            } else {
                low--;
                high++;
            }
            // Step 4: If even the best case is below zero, a close bracket has no partner.
            if (high < 0) {
                return false;
            }
            // Step 5: The count of open brackets can never be below zero.
            if (low < 0) {
                low = 0;
            }
        }
        // Step 6: It works if zero open brackets is one of the possible results.
        return low == 0;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String s = scanner.hasNextLine() ? scanner.nextLine() : "";
        System.out.println(solve(s));
    }
}
Hints (2)
  1. What do low and high mean?
  2. Why is low set back to 0?