Problem Statement in English
You’re given a string s of length n consisting of characters ‘T’ and ‘F’, and another string t of length m. You need to generate a string of length n + m - 1 that satisfies the following conditions:
- For every index
i(0-indexed) wheres[i]is ‘T’, the substring of the generated string starting at indexiand having lengthmmust be equal tot. - For every index
iwheres[i]is ‘F’, the substring of the generated string starting at indexiand having lengthmmust not be equal tot.
You need to return the lexicographically smallest string that satisfies these conditions. If there is no such string, return an empty string.
Approach
We use an optimistic greedy approach.
We first process all the ‘T’ characters in s and fill the corresponding positions in the answer string according to t. If while processing a ‘T’ character we find a conflict (i.e., a position that has already been filled with a different character), we can immediately return an empty string since it’s impossible to satisfy the conditions.
Next we fill all the remaining ‘?’ characters with ‘a’ to get the lexicographically smallest string.
Finally, we process all the ‘F’ characters in s. For each ‘F’, we check if the corresponding substring in the answer string matches t. If it does, we need to change at least one character in that substring to ensure it does not match t.
We look for the last ‘?’ character in that substring (which we initially set to ‘a’) and change it to ‘b’. If there are no ‘?’ characters left to change, it means we cannot satisfy the conditions for that ‘F’, and we return an empty string.
And we’re done!
Solution in Python
class Solution:
def generateString(self, s: str, t: str) -> str:
n, m = len(s), len(t)
ans = ['?'] * (n + m - 1) # ? indicates a pending position
# Process 'T'
for i, b in enumerate(s):
if b != 'T':
continue
# The substring must match t
for j, c in enumerate(t):
v = ans[i + j]
if v != '?' and v != c:
return ""
ans[i + j] = c
old_ans = ans
ans = ['a' if c == '?' else c for c in ans] # Initial default is 'a'
# Process 'F'
for i, b in enumerate(s):
if b != 'F':
continue
# Substring must not equal t
if ''.join(ans[i: i + m]) != t:
continue
# Locate the last pending position to modify
for j in range(i + m - 1, i - 1, -1):
if old_ans[j] == '?': # Change 'a' to 'b'
ans[j] = 'b'
break
else:
return ""
return ''.join(ans)
Complexity
Time: $O(n \cdot m)$
Since we may need to check each ‘F’ character against the substring of lengthmand also fill the answer string.Space: $O(n + m)$
Since we store the answer string and also need to keep track of the original pending positions.
Mistakes I Made
I had to look this up :(
And we are done.