Given a string s
, determine if it is valid.
A string s
is valid if, starting with an empty string t = ""
, you can transform t
into s
after performing the following operation any number of times:
"abc"
into any position in t
. More formally, t
becomes tleft + "abc" + tright
, where t == tleft + tright
. Note that tleft
and tright
may be empty.Return true
if s
is a valid string, otherwise, return false
.
Example 1:
Input: s = "aabcbc" Output: true Explanation: "" -> "abc" -> "aabcbc" Thus, "aabcbc" is valid.
Example 2:
Input: s = "abcabcababcc" Output: true Explanation: "" -> "abc" -> "abcabc" -> "abcabcabc" -> "abcabcababcc" Thus, "abcabcababcc" is valid.
Example 3:
Input: s = "abccba" Output: false Explanation: It is impossible to get "abccba" using the operation.
Constraints:
1 <= s.length <= 2 * 104
s
consists of letters 'a'
, 'b'
, and 'c'
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method for this problem involves repeatedly trying to simplify the given string by removing instances of "abc". We continue removing "abc" until the string is either empty or no longer contains "abc". If the string becomes empty, it's valid; otherwise, it's not.
Here's how the algorithm would work step-by-step:
def is_valid_after_substitutions(input_string):
modified_string = input_string
while True:
abc_index = modified_string.find("abc")
# If 'abc' is not found, break out of the loop
if abc_index == -1:
break
# Remove 'abc' from the string.
modified_string = modified_string[:abc_index] + modified_string[abc_index+3:]
# Check if the remaining string is empty.
if len(modified_string) == 0:
return True
else:
return False
The key idea is to repeatedly simplify the input string by removing the pattern "abc". We use a stack to keep track of the characters we've seen so far, and whenever we find "abc" on top of the stack, we remove it.
Here's how the algorithm would work step-by-step:
def is_valid_after_substitutions(input_string):
character_stack = []
for character in input_string:
character_stack.append(character)
# Check for 'abc' sequence on top of stack.
if len(character_stack) >= 3 and \
character_stack[-3] == 'a' and \
character_stack[-2] == 'b' and \
character_stack[-1] == 'c':
# Remove 'abc' from the stack.
character_stack.pop()
character_stack.pop()
character_stack.pop()
# If the stack is empty, the string is valid.
return not character_stack
Case | How to Handle |
---|---|
Null or empty input string | Return true if the string is null or empty because an empty string is considered valid after zero substitutions. |
Input string is 'abc' | Return true because 'abc' represents a single 'abc' substitution. |
Input string is 'ababcbc' | Return true; this is a valid sequence of substitutions. |
Input string contains characters other than 'a', 'b', or 'c' | Return false immediately as these characters make it invalid per the problem definition. |
Input string starts or ends with 'b' or 'c' | Return false immediately because the first 'abc' insertion always begins with 'a'. |
Maximum input string size (considering potential stack overflow with recursion) | An iterative approach is required to handle large input strings and avoid stack overflow. |
Input string contains uneven distribution of 'a', 'b', and 'c' | The algorithm should handle cases where the counts of 'a', 'b', and 'c' are not balanced, resulting in false. |
Input string is 'abccba' | Return false; 'abc' can only be substituted if in sequence. |