Minimum Number of Days to Eat N Oranges

hard graph bfs dp memoization

Problem

You have n oranges. Each day you may do exactly one of the following: eat one orange; if the current count is divisible by 2, eat n/2 oranges (halving the count); or if the current count is divisible by 3, eat 2·(n/3) oranges (leaving n/3). Return the minimum number of days needed to eat all n oranges.

Inputn = 10
Output4
10 → eat 1 → 9 → eat 6 (÷3) → 3 → eat 2 (÷3) → 1 → eat 1 → 0. That is 4 days.

from collections import deque

def min_days(n):
    seen = {n}
    q = deque([n])
    days = 0
    while q:
        for _ in range(len(q)):
            x = q.popleft()
            if x == 0:
                return days
            nxts = [x - 1]
            if x % 2 == 0:
                nxts.append(x // 2)
            if x % 3 == 0:
                nxts.append(x // 3)
            for y in nxts:
                if y not in seen:
                    seen.add(y)
                    q.append(y)
        days += 1
    return days
function minDays(n) {
  const seen = new Set([n]);
  let q = [n];
  let days = 0;
  while (q.length) {
    const next = [];
    for (const x of q) {
      if (x === 0) return days;
      const nxts = [x - 1];
      if (x % 2 === 0) nxts.push(x / 2);
      if (x % 3 === 0) nxts.push(x / 3);
      for (const y of nxts) {
        if (!seen.has(y)) {
          seen.add(y);
          next.push(y);
        }
      }
    }
    q = next;
    days++;
  }
  return days;
}
class Solution {
    public int minDays(int n) {
        Set<Integer> seen = new HashSet<>();
        Deque<Integer> q = new ArrayDeque<>();
        seen.add(n); q.add(n);
        int days = 0;
        while (!q.isEmpty()) {
            int sz = q.size();
            for (int i = 0; i < sz; i++) {
                int x = q.poll();
                if (x == 0) return days;
                List<Integer> nxts = new ArrayList<>();
                nxts.add(x - 1);
                if (x % 2 == 0) nxts.add(x / 2);
                if (x % 3 == 0) nxts.add(x / 3);
                for (int y : nxts) {
                    if (!seen.contains(y)) {
                        seen.add(y); q.add(y);
                    }
                }
            }
            days++;
        }
        return days;
    }
}
class Solution {
public:
    int minDays(int n) {
        unordered_set<int> seen{n};
        queue<int> q;
        q.push(n);
        int days = 0;
        while (!q.empty()) {
            int sz = q.size();
            for (int i = 0; i < sz; i++) {
                int x = q.front(); q.pop();
                if (x == 0) return days;
                vector<int> nxts{x - 1};
                if (x % 2 == 0) nxts.push_back(x / 2);
                if (x % 3 == 0) nxts.push_back(x / 3);
                for (int y : nxts) {
                    if (!seen.count(y)) {
                        seen.insert(y); q.push(y);
                    }
                }
            }
            days++;
        }
        return days;
    }
};
Time: O(log² n) Space: O(log² n)