Valid Parenthesis String

Updated on 07 July, 2025
Valid Parenthesis String header image

Problem Statement

The problem presents a string s that consists exclusively of the characters '(', ')', and '*'. Our objective is to determine whether or not the string is "valid" based on specific criteria. A string is deemed valid if every '(' has a subsequent matching ')', appearing after it, and vice versa. Additionally, the character '*' can be adaptively used either as a '(', ')', or not used at all (""). This flexibility with the '*' character introduces a layer of dynamism in verifying the string's validity. It is not merely a matter of counting the parentheses but rather ensuring that they can be correctly matched considering the possible interpretations of '*'.

Examples

Example 1

Input:

s = "()"

Output:

true

Example 2

Input:

s = "(*)"

Output:

true

Example 3

Input:

s = "(*))"

Output:

true

Constraints

  • 1 <= s.length <= 100
  • s[i] is '(', ')' or '*'.

Approach and Intuition

  1. The principle challenge lies in the various interpretations of the '*' character. It can serve as both a solution and a complication because its flexibility in role can help complete missing parts of the parenthesis structure or could potentially obstruct correct validation if misinterpreted.

  2. A strategic approach can involve using two counters—think of them as two scenarios:

    • One scenario optimistically counts '*' as ')' when evaluating from left to right.
    • Another scenario treats '*' as '(' when evaluating from right to left.
  3. By iterating from left to right:

    • Increase a counter for each '(' or '*' and decrease for each ')'.
    • If the counter goes negative, it means that there are more ')' than '(' and '*' combined at any point, indicating that the sequence is invalid.
  4. Similarly, evaluate from right to left:

    • Increment the counter for each ')' or '*' and decrement for each '('.
    • A drop into negative values suggests the existence of more '(' than ')' and '*' combined at any point from the reverse perspective.
  5. The string is only valid if, all through the checks, neither of the counters dip below zero, ensuring that every '(' can be matched with a ')' considering all possible sequences and uses of '*'.

  6. By sequentially considering and re-considering the role of '*' in both forward and backward passes, we effectively simulate all viable resolutions of '*', ensuring that if a valid combination exists, it will be accounted for through this approach.

This method efficiently tests for sequence validity using linear scans, making it computationally feasible given the constraint of the string length being up to 100 characters.

Solutions

  • C++
cpp
class Solution {
public:
    bool isValidParenthesisCombination(string str) {
        int leftCount = 0;
        int rightCount = 0;
        int strLen = str.length() - 1;
            
        for (int idx = 0; idx <= strLen; idx++) {
            if (str[idx] == '(' || str[idx] == '*') {
                leftCount++;
            } else {
                leftCount--;
            }
                
            if (str[strLen - idx] == ')' || str[strLen - idx] == '*') {
                rightCount++;
            } else {
                rightCount--;
            }
                
            if (leftCount < 0 || rightCount < 0) {
                return false;
            }
        }
            
        return true;
    }
};

The provided C++ solution is designed to determine if a string containing parentheses and wildcard characters is valid based on certain balance conditions. The main functionality resides in the isValidParenthesisCombination method of the Solution class. Here's the breakdown of how this code achieves its goal:

  • The function initializes two counters, leftCount and rightCount to track the balance of opening and closing parentheses from the left and right ends of the string, respectively.
  • It iterates through the string twice simultaneously: once from the beginning to the end and once from the end to the beginning.
  • For each character:
    • If the character is an opening parenthesis or a wildcard, leftCount is incremented.
    • If it's not, leftCount is decremented. This checks the balance when considering any wildcard as an opening parenthesis.
    • Similarly, for the reverse iteration:
      • If the character is a closing parenthesis or a wildcard, rightCount is incremented.
      • Otherwise, rightCount is decremented. This checks the balance when considering any wildcard as a closing parenthesis.
  • If at any point either leftCount or rightCount drops below zero, the string is immediately considered invalid, and the function returns false.
  • If both counters are non-negative throughout the iterations, the string is deemed valid, and the function returns true.

This approach ensures that the string can potentially form a valid sequence of balanced parentheses by treating wildcard characters as either opening or closing brackets, where necessary.

  • Java
java
class Solution {
    public boolean isValidSequence(String input) {
        int leftSide = 0;
        int rightSide = 0;
        int stringLength = input.length() - 1;
            
        for (int idx = 0; idx <= stringLength; idx++) {
            if (input.charAt(idx) == '(' || input.charAt(idx) == '*') {
                leftSide++;
            } else {
                leftSide--;
            }
                
            if (input.charAt(stringLength - idx) == ')' || input.charAt(stringLength - idx) == '*') {
                rightSide++;
            } else {
                rightSide--;
            }
                
            if (leftSide < 0 || rightSide < 0) {
                return false;
            }
        }
            
        return true;
    }
}

This Java solution tackles the problem of determining if a string containing parentheses and asterisks is valid. A valid string means every opening parenthesis '(' has a corresponding closing parenthesis ')'. Asterisks '*' can be treated either as a single right parenthesis ')', a single left parenthesis '(', or as an empty string "".

Consider the following approach to validate the sequence:

  • Initialize two counters: leftSide for tracking balance checking from the beginning of the string, and rightSide for tracking from the end.
  • Iterate through the string twice simultaneously from the beginning and the end.
  • For forward tracking (leftSide), increment the counter for each '(' and '*'. Decrement for every other character. If at any point leftSide drops below zero, the sequence is invalid.
  • For backward tracking (rightSide), increment the counter for each ')' and '*'. Decrement for any other character. Similar to the forward tracking, if rightSide drops below zero, the sequence is invalid.
  • After iterating through the string, if neither counter has dropped below zero, the string is considered valid.

This approach effectively checks balance from both ends, allowing asterisks to flexibly serve as either bracket type to balance the sequence. This efficient method ensures the string adheres to the rules of valid parentheses sequence, augmented by the versatility of asterisks. Use this implementation to quickly validate potentially complex sequences with optimally balanced operations.

  • Python
python
class Solution:
    def validatePattern(self, pattern: str) -> bool:
        left_count = 0
        right_count = 0
        pattern_len = len(pattern) - 1
            
        for index in range(pattern_len + 1):
            if pattern[index] == '(' or pattern[index] == '*':
                left_count += 1
            else:
                left_count -= 1
    
            if pattern[pattern_len - index] == ')' or pattern[pattern_len - index] == '*':
                right_count += 1
            else:
                right_count -= 1
    
            if left_count < 0 or right_count < 0:
                return False
    
        return True

The provided Python code defines a method, validatePattern, within a class Solution which checks whether a given string, consisting of the characters '(', ')', and '*', forms a valid parenthesis pattern. The method ensures that the pattern remains open-close balanced when traversed from both the left and right sides.

Code Explanation:

  • Initialize two counters, left_count and right_count, to zero. These track the balance of parenthesis as the string is analyzed from the left and right, respectively.
  • Check each character in the string pattern:
    • Increase left_count when encountering either '(' or '*'. Otherwise, decrease it.
    • Simultaneously, check the string from the right end using right_count. Increase for ')' or '*', decrease for other cases.
    • If at any point, left_count or right_count falls below zero, the function returns False, indicating the string cannot maintain a balanced state.
  • If the entire string is processed without the counters dropping below zero, return True, reflecting a valid parenthesis pattern.

Usage:

   

Invoke the validatePattern function by passing the desired string to be validated, ensuring the paired implementation respects the nested or balanced requirements of typical parenthesis in programming or mathematics. Note that '*' acts as a wildcard that can represent either parenthesis or an empty string, providing flexibility in balancing pairs.

Comments

No comments yet.