Problem
You want to form aĀ target
Ā string ofĀ lowercase letters.
At the beginning, your sequence isĀ target.length
Ā '?'
Ā marks.Ā You also have aĀ stamp
Ā of lowercase letters.
On each turn, you may place the stamp over the sequence, and replace every letter in the sequence with the corresponding letter from the stamp.Ā You can make up toĀ 10 * target.length
Ā turns.
For example, if the initial sequence isĀ “?????”, and your stamp isĀ "abc"
,Ā then you may makeĀ “abc??”, “?abc?”, “??abc”Ā in the first turn.Ā (Note that the stamp must be fully contained in the boundaries of the sequence in order to stamp.)
If the sequence is possible to stamp, then return an array ofĀ the index of the left-most letter being stamped at each turn.Ā If the sequence is not possible to stamp, return an empty array.
For example, if the sequence isĀ “ababc”, and the stamp isĀ "abc"
, then we could return the answerĀ [0, 2]
, corresponding to the movesĀ “?????” -> “abc??” -> “ababc”.
Also, if the sequence is possible to stamp, it is guaranteed it is possible to stamp withinĀ 10 * target.length
Ā moves.Ā Any answers specifying more than this number of movesĀ will not be accepted.
Example 1:
Input: stamp = "abc", target = "ababc" Output: [0,2] ([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]
Note:
1 <= stamp.length <= target.length <= 1000
stamp
Ā andĀtarget
Ā only contain lowercase letters.
Solution: Greedy + Reverse Simulation
Reverse the stamping process. Each time find a full or partial match. Replace the matched char to ‘?’.
Don’t forget the reverse the answer as well.
T = “ababc”, S = “abc”
T = “ab???”, index = 2
T = “?????”, index = 0
ans = [0, 2]
Time complexity: O((T – S)*S)
Space complexity: O(T)
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
// Author: Huahua, running time: 12 ms class Solution { public: vector<int> movesToStamp(string stamp, string target) { vector<int> ans; vector<int> seen(target.length()); int total = 0; while (total < target.length()) { bool found = false; for (int i = 0; i <= target.length() - stamp.length(); ++i) { if (seen[i]) continue; int l = unStamp(stamp, target, i); if (l == 0) continue; seen[i] = 1; total += l; ans.push_back(i); found = true; } if (!found) return {}; } reverse(begin(ans), end(ans)); return ans; } private: int unStamp(const string& stamp, string& target, int s) { int l = stamp.size(); for (int i = 0; i < stamp.length(); ++i) { if (target[s + i] == '?') --l; else if (target[s + i] != stamp[i]) return 0; } if (l != 0) std::fill(begin(target) + s, begin(target) + s + stamp.length(), '?'); return l; } }; |