Quick Overview

Decide whether a string of parentheses and stars can become a balanced parenthesis string when each star may independently act as an opening parenthesis, a closing parenthesis or an empty string. Tests reasoning over many possible replacements at once and edge cases with unmatched parentheses near either end.

Decide Whether a Parenthesis String With Star Wildcards Can Be Balanced

Company: Oracle

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

Given a string made only of the characters `(`, `)` and `*`, decide whether it can be turned into a balanced parenthesis string by replacing every `*`, independently of the others, with `(`, with `)`, or with the empty string. A parenthesis string is balanced when, reading from left to right, the number of `)` seen so far never exceeds the number of `(` seen so far, and the two counts are equal at the end. The empty string is balanced. ### Function Signature ```python def can_be_balanced(s: str) -> bool: ``` ### Rules - Each `*` is replaced on its own; two stars may be replaced differently. - The `(` and `)` characters stay exactly where they are; only stars change. - Return `True` if at least one way of replacing the stars yields a balanced string, and `False` otherwise. ### Constraints - `1 <= len(s) <= 100` - Every character of `s` is `(`, `)` or `*`. ### Examples **Example 1** ```text Input: s = "(*))" Output: True ``` Replacing the star with `(` gives `(())`, which is balanced. **Example 2** ```text Input: s = ")*(" Output: False ``` The `)` at index 0 has nothing before it that could open a pair, so every replacement fails at the first character. **Example 3** ```text Input: s = "*(*" Output: True ``` Replacing the first star with the empty string and the second with `)` gives `()`.

Overview: Decide whether a string of parentheses and stars can become a balanced parenthesis string when each star may independently act as an opening parenthesis, a closing parenthesis or an empty string. Tests reasoning over many possible replacements at once and edge cases with unmatched parentheses near either end.

Given a string `s` made only of the characters `(`, `)` and `*`, decide whether it can be turned into a balanced parenthesis string by replacing every `*`, independently of the others, with `(`, with `)`, or with the empty string. A parenthesis string is **balanced** when, reading from left to right, the number of `)` seen so far never exceeds the number of `(` seen so far, and the two counts are equal at the end. The empty string is balanced. Implement `can_be_balanced(s)`. ### Rules - Each `*` is replaced on its own; two stars may be replaced differently. - The `(` and `)` characters stay exactly where they are; only stars change. - Return `True` if at least one way of replacing the stars yields a balanced string, and `False` otherwise (`true` / `false` in JavaScript, Java and C++). ### Examples **Example 1** ```text Input: s = "(*))" Output: True ``` Replacing the star with `(` gives `(())`, which is balanced. **Example 2** ```text Input: s = ")*(" Output: False ``` The `)` at index 0 has nothing before it that could open a pair, so every replacement fails at the first character. ### Constraints - `1 <= len(s) <= 100` - Every character of `s` is `(`, `)` or `*`. The answer is a single boolean; no numeric value crossing the function boundary can exceed 2^31-1.

Constraints

  • 1 <= len(s) <= 100
  • Every character of s is '(', ')' or '*'.

Examples

Input: ('(',)

Expected Output: False

Explanation: A lone '(' has nothing after it that could close it.

Input: (')',)

Expected Output: False

Explanation: A lone ')' has nothing before it that could open a pair.

Hints

  1. The balanced condition has two parts: a condition on every prefix while reading left to right, and an equality of counts at the end. A replacement must satisfy both.
  2. An unmatched '(' can only be closed by a ')' or a '*' that comes after it; an unmatched ')' can only be opened by a '(' or a '*' that comes before it.
  3. A '*' may also vanish, so a star is never forced to create an extra bracket.

Loading coding console...

Show the approach

Approach

Algorithm: scan left to right while tracking the range of reachable balances, where the balance of a prefix is (number of '(') minus (number of ')') after its stars are replaced. lo and hi are the smallest and largest balance reachable by replacements whose every prefix balance stayed at or above zero.

Invariant: after each character the reachable set is exactly every integer in [lo, hi]. A '(' shifts the range up by one, a ')' shifts it down by one, and a '*' (choices +1, 0 or -1) widens it to [lo - 1, hi + 1]; the union of three consecutive shifts of an integer interval is again an interval, so no gaps appear.

Correctness: a replacement is valid only if no prefix balance is negative, so after each step the range is intersected with [0, infinity). If hi < 0 no replacement survives and the answer is False immediately; otherwise lo becomes max(lo, 0). At the end a balanced replacement exists exactly when balance 0 is reachable, and because 0 <= lo <= hi this is the test lo == 0.

Edge cases: a single '(' leaves lo = 1 (False); a single ')' drives hi below zero (False); a string of only stars keeps lo at 0 (True, every star vanishes); an unmatched ')' before any star fails immediately because later stars cannot open it; an empty string (outside the stated constraints) returns True because the empty string is balanced.

Time complexity:
O(n)
Space complexity:
O(1)