Grokking LinkedIn Coding Interview
Ask Author
Back to course home

0% completed

Vote For New Content
Solution: Valid Parenthesis String
Table of Contents

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible

Problem Statement

Given a string s containing multiple occurrences of characters: '(', ')' and '*', return true if s is valid. Otherwise, return false.

A string is valid if it follows below rules:

  • Any left parenthesis '(' must be closed by corresponding right parenthesis ')'.
  • Any right parenthesis ')' must have a corresponding left parenthesis '('.
  • '*' can be used as a single left parenthesis ')' or a single right parenthesis '(' or an empty string "".

Examples

  • Example 1:

    • Input: s= "*())"
    • Expected Output: true
    • Justification: The asterisk can be treated as an open parenthesis, making the string "(())."
  • Example 2:

    • **Input: s = "((*()**"
    • Expected Output: true
    • **Justification: The first and second asterisks can be treated as close parenthesis, and the third asterisk can be treated as an empty string, resulting in a balanced set of parentheses "(()())."
  • Example 3:

    • Input: s = "())*"
    • Expected Output: false
    • Justification: There's no way to interpret the asterisk that would balance the extra close parenthesis at the start.

Solution

This solution employs a smart strategy to determine if a string with parentheses and asterisks is valid. It navigates through each character, adjusting counts to represent possible states of open parentheses. The core idea revolves around maintaining two counters: a low counter (lo) to represent the minimum possible open parentheses, assuming asterisks are used optimally, and a high counter (hi) to represent the maximum possible open parentheses, assuming all asterisks are treated as open parentheses.

This dual-counter approach captures the flexibility of asterisks, which can act as either open or close parentheses or be omitted. By updating these counters based on current character analysis and ensuring our high counter never drops below zero (which would indicate too many closing parentheses), we maintain a balance check. If, by the end of the string, our low counter resets to zero, it signifies that there's at least one valid way to interpret the string as properly balanced, making this method both efficient and effective in handling the problem's inherent ambiguity.

Step-by-step Algorithm

  1. Initialize two variables, lo and hi, to zero. These will track the lower and upper bounds of the count of open parentheses.
  2. Iterate through each character of the string s:
    • If the character is an open parenthesis '(', increment both lo and hi by 1. This is because an open parenthesis definitely increases the number of unclosed parentheses.
    • If the character is a close parenthesis ')', decrement both lo and hi by 1. This reflects closing an open parenthesis. However, since lo represents a minimum, it cannot be negative; thus, if lo drops below 0, reset it to 0.
    • If the character is an asterisk '*', increment hi by 1 (as it could act as an open parenthesis) but decrement lo by 1 (as it could act as a closing parenthesis). However, lo is adjusted to a minimum of 0 to avoid negative values.
    • After processing each character, check if hi is less than 0. If true, break the loop as it indicates there are too many closing parentheses, making the string invalid.
  3. After iterating through the string, check if lo equals 0. A lo of 0 indicates that there is a valid configuration where all open parentheses can be closed, thus the string is valid.

Algorithm Walkthrough

Given the input "((*()**", let's apply the algorithm:

  1. lo = 0, hi = 0 at the start.
  2. First character '(': increment both lo and hi by 1.
    • lo = 1, hi = 1.
  3. Second character '(': increment both lo and hi by 1 again.
    • lo = 2, hi = 2.
  4. Third character '*': lo could represent a closing parenthesis, so decrement by 1 (but not less than 0), and hi could represent an open parenthesis, so increment by 1.
    • lo = 1 (minimum of 1 and not less), hi = 3.
  5. Fourth character '(': increment both lo and hi by 1.
    • lo = 2, hi = 4.
  6. Fifth character ')': decrement both lo and hi by 1.
    • lo = 1, hi = 3.
  7. Sixth character '*': treat '*' similarly to the third character; decrement lo by 1 (to a minimum of 0) and increment hi.
    • lo = 0, hi = 4.
  8. Seventh character '*': continue with the same approach for '*'.
    • lo = 0, hi = 5.

After completing the iteration, lo is 0, which indicates the string "((*()**" can be valid, assuming asterisks are optimally used either as open parentheses, close parentheses, or not used at all.

Code

Python3
Python3

. . . .

Complexity Analysis

  • Time Complexity: O(n), where n is the length of the input string. The algorithm iterates through the string once.
  • Space Complexity: O(1), as the algorithm uses only a constant amount of extra space.

.....

.....

.....

Like the course? Get enrolled and start learning!

Table of Contents

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible