Freedom Trail

hard string dp dfs bfs

Problem

Ring is a string of lowercase letters. key is the word you must spell. Rotation cost 1 each step (either direction); each spell costs 1. Return min total cost.

Inputring = "godding", key = "gd"
Output4
DP scans key from right to left, picking the best ring position per character.

def find_rotate_steps(ring, key):
    from collections import defaultdict
    n, m = len(ring), len(key)
    pos = defaultdict(list)
    for i, c in enumerate(ring): pos[c].append(i)
    INF = float("inf")
    dp = [INF] * n; dp[0] = 0
    def dist(a, b): return min(abs(a - b), n - abs(a - b))
    cur = {0: 0}
    for c in key:
        nxt = {}
        for j in pos[c]:
            best = INF
            for p, v in cur.items():
                best = min(best, v + dist(p, j) + 1)
            nxt[j] = best
        cur = nxt
    return min(cur.values())
function findRotateSteps(ring, key) {
  const n = ring.length;
  const pos = {};
  for (let i = 0; i < n; i++) (pos[ring[i]] ??= []).push(i);
  const dist = (a, b) => Math.min(Math.abs(a - b), n - Math.abs(a - b));
  let cur = new Map([[0, 0]]);
  for (const c of key) {
    const next = new Map();
    for (const j of pos[c]) {
      let best = Infinity;
      for (const [p, v] of cur) best = Math.min(best, v + dist(p, j) + 1);
      next.set(j, best);
    }
    cur = next;
  }
  return Math.min(...cur.values());
}
class Solution {
    public int findRotateSteps(String ring, String key) {
        int n = ring.length();
        Map> pos = new HashMap<>();
        for (int i = 0; i < n; i++) pos.computeIfAbsent(ring.charAt(i), k -> new ArrayList<>()).add(i);
        Map cur = new HashMap<>(); cur.put(0, 0);
        for (char c : key.toCharArray()) {
            Map next = new HashMap<>();
            for (int j : pos.get(c)) {
                int best = Integer.MAX_VALUE;
                for (var e : cur.entrySet()) {
                    int d = Math.min(Math.abs(e.getKey() - j), n - Math.abs(e.getKey() - j));
                    best = Math.min(best, e.getValue() + d + 1);
                }
                next.put(j, best);
            }
            cur = next;
        }
        return Collections.min(cur.values());
    }
}
int findRotateSteps(string ring, string key) {
    int n = ring.size();
    unordered_map> pos;
    for (int i = 0; i < n; i++) pos[ring[i]].push_back(i);
    unordered_map cur{{0, 0}};
    for (char c : key) {
        unordered_map next;
        for (int j : pos[c]) {
            int best = INT_MAX;
            for (auto& [p, v] : cur) {
                int d = min(abs(p - j), n - abs(p - j));
                best = min(best, v + d + 1);
            }
            next[j] = best;
        }
        cur = next;
    }
    int ans = INT_MAX;
    for (auto& [_, v] : cur) ans = min(ans, v);
    return ans;
}
Time: O(|ring|·|key|·k) Space: O(|ring|)