We are given that the string "abc"
is valid.
From any valid string V
, we may split V
into two pieces X
and Y
such that X + Y
(X
concatenated with Y
) is equal to V
. (X
or Y
may be empty.) Then, X + "abc" + Y
is also valid.
If for example S = "abc"
, then examples of valid strings are: "abc", "aabcbc", "abcabc", "abcabcababcc"
. Examples of invalid strings are: "abccba"
, "ab"
, "cababc"
, "bac"
.
Return true
if and only if the given string S
is valid.
Example 1:
Input: "aabcbc"
Output: true
Explanation:
We start with the valid string "abc".
Then we can insert another "abc" between "a" and "bc", resulting in "a" + "abc" + "bc" which is "aabcbc".
Example 2:
Input: "abcabcababcc"
Output: true
Explanation:
"abcabcabc" is valid after consecutive insertings of "abc".
Then we can insert "abc" before the last letter, resulting in "abcabcab" + "abc" + "c" which is "abcabcababcc".
Example 3:
Input: "abccba"
Output: false
Example 4:
Input: "cababc"
Output: false
Note:
1 <= S.length <= 20000
S[i]
is'a'
,'b'
, or'c'
Brute force solution, O(n^2), scan through the entire string and remove all "abc" patterns, repeat this process until the string is empty or reaches a stable state that no "abc" can be found.
class Solution { public boolean isValid(String S) { String before = S, after = null; while(!before.equals("")) { after = before.replaceAll("abc", ""); if(after.length() == before.length()) { return false; } before = after; } return true; } }
Optimal solution with Stack, O(n) runtime, O(n) space
Intuition: each time we remove "abc", we need to keep the previously visted characters in the same sequence as before the removal. Each time we see a 'c', we need to check its two closest two predecessors are 'a' and 'b'. This requires LIFO, hence we should use stack.
class Solution { public boolean isValid(String S) { Stack<Character> stack = new Stack<>(); for(char c : S.toCharArray()) { if(c == '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(c); } } return stack.size() == 0; } }