Check If Word Is Valid After Substitutions

medium stack string simulation

Problem

We start with the empty string and may repeatedly insert the substring "abc" at any position. A string is valid if it can be produced this way. Given a string s, return true if it is valid. Equivalently, scanning left to right, every "abc" pattern that forms can be collapsed, and the whole string must reduce to empty.

Inputs = "aabcbc"
Outputtrue
"" → "abc" → "aabcbc": insert "abc" then insert another "abc" inside, so it is valid.

def is_valid(s):
    stack = []
    for ch in s:
        if ch == 'c':
            if len(stack) < 2 or stack[-1] != 'b' or stack[-2] != 'a':
                return False
            stack.pop()
            stack.pop()
        else:
            stack.append(ch)
    return len(stack) == 0
function isValid(s) {
  const stack = [];
  for (const ch of s) {
    if (ch === 'c') {
      const n = stack.length;
      if (n < 2 || stack[n - 1] !== 'b' || stack[n - 2] !== 'a') return false;
      stack.pop();
      stack.pop();
    } else {
      stack.push(ch);
    }
  }
  return stack.length === 0;
}
class Solution {
    public boolean isValid(String s) {
        Deque<Character> stack = new ArrayDeque<>();
        for (char ch : s.toCharArray()) {
            if (ch == 'c') {
                if (stack.size() < 2) return false;
                char b = stack.pop();
                char a = stack.pop();
                if (a != 'a' || b != 'b') return false;
            } else {
                stack.push(ch);
            }
        }
        return stack.isEmpty();
    }
}
bool isValid(string s) {
    string stack;
    for (char ch : s) {
        if (ch == 'c') {
            int n = stack.size();
            if (n < 2 || stack[n - 1] != 'b' || stack[n - 2] != 'a') return false;
            stack.pop_back();
            stack.pop_back();
        } else {
            stack.push_back(ch);
        }
    }
    return stack.empty();
}
Time: O(n) Space: O(n)