We use cookies (including Google cookies) to personalize ads and analyze traffic. By continuing to use our site, you accept our Privacy Policy.

Check if a Parentheses String Can Be Valid

Difficulty: Medium


Problem Description

Given a parentheses string s and a string locked, both of length n, determine if it is possible to make s a valid parentheses string by changing some characters in s based on the constraints provided by locked. If locked[i] is '1', you cannot change s[i]; if it is '0', you can change s[i] to either '(' or ')'. Return true if you can make s a valid parentheses string, otherwise return false.


Key Insights

  • A valid parentheses string must have balanced parentheses; the number of opening and closing parentheses must match.
  • The number of changes allowed is determined by where locked is '0'.
  • We can keep track of the net balance of parentheses by treating ( as +1 and ) as -1.
  • We need to ensure that at no point in the string does the balance go negative, which indicates more closing parentheses than opening ones at that point.
  • Finally, after processing the entire string, the total balance must be zero or we need to account for the remaining changes possible.

Space and Time Complexity

Time Complexity: O(n) - We iterate through the string s once to determine if it can be made valid. Space Complexity: O(1) - We use a constant amount of space for counters.


Solution

To solve the problem, we can use a greedy approach. We will iterate through the string s while maintaining a balance counter and a variable to track the number of changes that can be made. At each character in the string:

  1. If the character is '(', increment the balance.
  2. If the character is ')', decrement the balance.
  3. If the character is locked as '0', treat it as either '(' or ')' based on the current balance to maintain validity.
  4. If at any point the balance goes negative, we cannot make the string valid.
  5. After processing the string, ensure that the final balance can be adjusted using the changes allowed.

Code Solutions

def canBeValid(s: str, locked: str) -> bool:
    if len(s) % 2 != 0:
        return False
    
    open_needed = 0
    close_needed = 0
    for i in range(len(s)):
        if locked[i] == '1':
            if s[i] == '(':
                open_needed += 1
            else:
                close_needed += 1
        else:
            # s[i] can be either '(' or ')'
            if open_needed > close_needed:
                close_needed += 1
            else:
                open_needed += 1
    
    return open_needed == close_needed
← Back to All Questions