Stamping The Sequence

hard string greedy

Problem

Given strings stamp and target, return a sequence of stamping positions that produces target from an all-'?' string. Return [] if impossible.

Inputstamp = "abc", target = "ababc"
Output[0,2]
Stamp at 2 (overrides) then 0; reverse the sequence to play back forward.

def movesToStamp(stamp, target):
    t = list(target)
    s = list(stamp)
    moves = []
    placed = True
    total_changed = 0
    star = ['?'] * len(t)
    while placed:
        placed = False
        for i in range(len(t) - len(s) + 1):
            changed = 0
            valid = False
            for j in range(len(s)):
                if t[i + j] == '?': continue
                if t[i + j] != s[j]: changed = -1; break
                valid = True
                changed += 1
            if changed > 0 and valid:
                for j in range(len(s)): t[i + j] = '?'
                moves.append(i)
                placed = True
                total_changed += changed
                if total_changed == len(target): return moves[::-1]
    return [] if any(c != '?' for c in t) else moves[::-1]
function movesToStamp(stamp, target) {
  const t = target.split(''), s = stamp.split('');
  const moves = [];
  let placed = true, total = 0;
  while (placed) {
    placed = false;
    for (let i = 0; i <= t.length - s.length; i++) {
      let changed = 0, valid = false;
      for (let j = 0; j < s.length; j++) {
        if (t[i + j] === '?') continue;
        if (t[i + j] !== s[j]) { changed = -1; break; }
        valid = true; changed++;
      }
      if (changed > 0 && valid) {
        for (let j = 0; j < s.length; j++) t[i + j] = '?';
        moves.push(i); placed = true; total += changed;
        if (total === target.length) return moves.reverse();
      }
    }
  }
  return t.some(c => c !== '?') ? [] : moves.reverse();
}
class Solution {
    public int[] movesToStamp(String stamp, String target) {
        char[] t = target.toCharArray(), s = stamp.toCharArray();
        List<Integer> moves = new ArrayList<>();
        boolean placed = true; int total = 0;
        while (placed) {
            placed = false;
            for (int i = 0; i <= t.length - s.length; i++) {
                int changed = 0; boolean valid = false;
                for (int j = 0; j < s.length; j++) {
                    if (t[i + j] == '?') continue;
                    if (t[i + j] != s[j]) { changed = -1; break; }
                    valid = true; changed++;
                }
                if (changed > 0 && valid) {
                    for (int j = 0; j < s.length; j++) t[i + j] = '?';
                    moves.add(i); placed = true; total += changed;
                }
            }
        }
        for (char c : t) if (c != '?') return new int[0];
        int[] out = new int[moves.size()];
        for (int i = 0; i < out.length; i++) out[i] = moves.get(moves.size() - 1 - i);
        return out;
    }
}
vector<int> movesToStamp(string stamp, string target) {
    string t = target, s = stamp;
    vector<int> moves;
    bool placed = true; int total = 0;
    while (placed) {
        placed = false;
        for (int i = 0; i + (int)s.size() <= (int)t.size(); i++) {
            int changed = 0; bool valid = false;
            for (int j = 0; j < (int)s.size(); j++) {
                if (t[i + j] == '?') continue;
                if (t[i + j] != s[j]) { changed = -1; break; }
                valid = true; changed++;
            }
            if (changed > 0 && valid) {
                for (int j = 0; j < (int)s.size(); j++) t[i + j] = '?';
                moves.push_back(i); placed = true; total += changed;
            }
        }
    }
    for (char c : t) if (c != '?') return {};
    reverse(moves.begin(), moves.end());
    return moves;
}
Time: O((n − m) · m · rounds) Space: O(n)