You are given two strings stamp and target. Initially, there is a string s of length target.length with all s[i] == '?'.
In one turn, you can place stamp over s and replace every letter in the s with the corresponding letter from stamp.
stamp = "abc" and target = "abcba", then s is "?????" initially. In one turn you can:
stamp at index 0 of s to obtain "abc??",stamp at index 1 of s to obtain "?abc?", orstamp at index 2 of s to obtain "??abc".stamp must be fully contained in the boundaries of s in order to stamp (i.e., you cannot place stamp at index 3 of s).We want to convert s to target using at most 10 * target.length turns.
Return an array of the index of the left-most letter being stamped at each turn. If we cannot obtain target from s within 10 * target.length turns, return an empty array.
Example 1:
Input: stamp = "abc", target = "ababc" Output: [0,2] Explanation: Initially s = "?????". - Place stamp at index 0 to get "abc??". - Place stamp at index 2 to get "ababc". [1,0,2] would also be accepted as an answer, as well as some other answers.
Example 2:
Input: stamp = "abca", target = "aabcaca" Output: [3,0,1] Explanation: Initially s = "???????". - Place stamp at index 3 to get "???abca". - Place stamp at index 0 to get "abcabca". - Place stamp at index 1 to get "aabcaca".
Constraints:
1 <= stamp.length <= target.length <= 1000stamp and target consist of lowercase English letters.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 strategy involves trying all possible placements of the stamp on the target sequence. For each potential placement, we check if stamping at that location results in a match with part of the target. We repeat this process for every possible starting point and collect the successful stamp placements.
Here's how the algorithm would work step-by-step:
def stamping_the_sequence_brute_force(stamp, target): stamp_length = len(stamp)
target_length = len(target)
possible_placements = []
# Iterate through all possible starting positions of the stamp
for start_position in range(target_length - stamp_length + 1):
match = True
for i in range(stamp_length):
if target[start_position + i] != '?' and target[start_position + i] != stamp[i]:
match = False
break
# Add the starting position if the stamp matches
if match:
possible_placements.append(start_position)
# Check if the possible placements can transform the target
for i in range(1 << len(possible_placements)):
temp_target = ['?'] * target_length
valid = True
placements_used = []
# Iterate through each possible placement and determine which ones to use
for j in range(len(possible_placements)):
if (i >> j) & 1:
placements_used.append(possible_placements[j])
# Apply the chosen stamps to the temporary target sequence
for placement in placements_used:
for k in range(stamp_length):
temp_target[placement + k] = stamp[k]
# Verify if the temporary target is the same as the original target
for index in range(target_length):
if temp_target[index] != target[index]:
valid = False
break
# If temp target is equal to the target return the placements
if valid:
return placements_used
return []The goal is to work backwards. We repeatedly try to perfectly match the stamp onto the target, and if we do, we 'erase' the stamped section and count that as a move. We continue until the target is entirely stamped over.
Here's how the algorithm would work step-by-step:
def movesToStamp(stamp, target):
stamp_length = len(stamp)
target_length = len(target)
stamped = ['?'] * target_length
stamped_string = ''.join(stamped)
result = []
visited = [False] * target_length
while ''.join(stamped) != target:
found = False
for i in range(target_length - stamp_length + 1):
if not visited[i] and canStamp(stamp, target, i):
result.append(i)
visited[i] = True
replaceWithQuestionMarks(target, i, stamp_length, stamped)
found = True
if not found:
return []
result.reverse()
return result
def canStamp(stamp, target, position):
for i in range(len(stamp)):
if target[position + i] != stamp[i] and target[position + i] != '?':
return False
return True
def replaceWithQuestionMarks(target, position, stamp_length, stamped):
# Replace stamped section with question marks.
for i in range(stamp_length):
stamped[position + i] = '?'
| Case | How to Handle |
|---|---|
| Empty stamp string | If the stamp is empty, the target can only be stamped if it is also empty, otherwise return an empty list. |
| Empty target string | If the target is empty, the stamp must also be empty; return an empty list if the stamp is not empty. |
| Stamp longer than target | If the stamp is longer than the target, it is impossible to stamp; return an empty list. |
| Stamp and target are identical | Return a list containing index 0 representing the single stamp location. |
| Target cannot be stamped at all | The algorithm will exhaust all possible stamp locations and return an empty list if the target remains unstamped. |
| Stamp consists of a single repeated character, and target consists of only this character, but target length is not a multiple of stamp length. | Even if the stamp's characters are present in the target, ensure all positions can be covered. |
| Large stamp and target sizes can lead to performance issues with naive implementations. | Employ a more efficient algorithm, such as a queue-based or greedy approach, to handle large inputs within the time constraint. |
| Multiple valid stamping orders exist | Return any valid order that successfully stamps the target; the problem statement allows for multiple solutions. |