Problem Statement in English
You are given a string s and an integer k. You can perform the following operation on s any number of times:
- Choose two indices
iandjsuch that0 <= i < j < s.lengthands[i] == s[j]. Then, merge the the character at indexjwith the character at indexiand remove the character at indexjfroms.
Return the resulting string after performing the operation until you can no longer perform it.
Approach
This is a stack question.
We just iterate over the string and maintain a hashmap to store the last index of each character.
We also maintain a reduction variable to keep track of how many characters we have removed from the string. This is because the index of subsequent characters will change after we remove characters from the string. To be precise, they will decrease by the number of characters we have removed from the string.
If the last time we saw the current character is within k distance from the current index (after accounting for the reduction), then we can merge the characters and remove the current character from the string. We also update the reduction variable.
If the last time we saw the current character is not within k distance from the current index, then we update the last index of the current character in the hashmap and add the current character to the stack.
Finally, we join the characters in the stack to get the resulting string.
And we’re done!
Solution in Python
class Solution:
def mergeCharacters(self, s: str, k: int) -> str:
stack = []
hm = {}
reduction = 0
for i in range(len(s)):
c = s[i]
if c in hm and i - reduction - hm[c] <= k:
reduction += 1
else:
hm[c] = i - reduction
stack.append(c)
return "".join(stack)
Complexity
Time: $O(n)$
Since we iterate over the string once.Space: $O(n)$
Since we store the stack and the hashmap.
And we are done.