Minimum Number of Operations to Make X and Y Equal

medium bfs dp memoization

Problem

You are given two positive integers x and y. In one operation you may do any of the following to x: divide it by 11 (only when x is a multiple of 11), divide it by 5 (only when x is a multiple of 5), subtract 1, or add 1. Return the smallest number of operations needed to turn x into y.

Inputx = 26, y = 1
Output3
26 → 25 (subtract 1) → 5 (divide by 5) → 1 (divide by 5). Three operations, which is the fewest possible.

from collections import deque

def minimum_operations(x, y):
    if x <= y:
        return y - x
    seen = {x}
    q = deque([x])
    steps = 0
    while q:
        for _ in range(len(q)):
            v = q.popleft()
            if v == y:
                return steps
            nxt = [v - 1, v + 1]
            if v % 11 == 0:
                nxt.append(v // 11)
            if v % 5 == 0:
                nxt.append(v // 5)
            for w in nxt:
                if w >= 0 and w not in seen:
                    seen.add(w)
                    q.append(w)
        steps += 1
    return steps
function minimumOperations(x, y) {
  if (x <= y) return y - x;
  const seen = new Set([x]);
  let q = [x];
  let steps = 0;
  while (q.length) {
    const next = [];
    for (const v of q) {
      if (v === y) return steps;
      const cand = [v - 1, v + 1];
      if (v % 11 === 0) cand.push(v / 11);
      if (v % 5 === 0) cand.push(v / 5);
      for (const w of cand) {
        if (w >= 0 && !seen.has(w)) {
          seen.add(w);
          next.push(w);
        }
      }
    }
    q = next;
    steps += 1;
  }
  return steps;
}
class Solution {
    public int minimumOperations(int x, int y) {
        if (x <= y) return y - x;
        Set<Integer> seen = new HashSet<>();
        seen.add(x);
        Queue<Integer> q = new LinkedList<>();
        q.add(x);
        int steps = 0;
        while (!q.isEmpty()) {
            int size = q.size();
            for (int i = 0; i < size; i++) {
                int v = q.poll();
                if (v == y) return steps;
                int[] cand = buildMoves(v);
                for (int w : cand) {
                    if (w >= 0 && seen.add(w)) q.add(w);
                }
            }
            steps += 1;
        }
        return steps;
    }
}
int minimumOperations(int x, int y) {
    if (x <= y) return y - x;
    unordered_set<int> seen{ x };
    queue<int> q;
    q.push(x);
    int steps = 0;
    while (!q.empty()) {
        int size = q.size();
        for (int i = 0; i < size; i++) {
            int v = q.front(); q.pop();
            if (v == y) return steps;
            vector<int> cand = { v - 1, v + 1 };
            if (v % 11 == 0) cand.push_back(v / 11);
            if (v % 5 == 0) cand.push_back(v / 5);
            for (int w : cand) {
                if (w >= 0 && !seen.count(w)) {
                    seen.insert(w);
                    q.push(w);
                }
            }
        }
        steps += 1;
    }
    return steps;
}
Time: O(x) Space: O(x)