Jump Game IV

Hard
Watch on YouTube ↗

Solution

class Solution {
    public int minJumps(int[] arr) {
        int n = arr.length;

        // Base cases
        if (n == 1) return 0;
        if (n == 2) return 1;

        // Map each value to all indices that share it (for same-value jumps)
        // Time: O(n), Space: O(n)
        HashMap<Integer, List<Integer>> hmap = new HashMap<>();
        for (int i = 0; i < n; i++) {
            if (!hmap.containsKey(arr[i]))
                hmap.put(arr[i], new ArrayList<>());
            hmap.get(arr[i]).add(i);
        }

        // BFS to find shortest path (min jumps) from index 0 to index n-1
        Queue<Integer> q = new LinkedList<>();
        q.add(0);

        int[] dist = new int[n];
        Arrays.fill(dist, -1);
        dist[0] = 0;

        while (!q.isEmpty()) {
            int curr = q.remove();

            if (curr == n - 1) return dist[n - 1];

            // Jump left
            if (curr - 1 >= 0 && dist[curr - 1] < 0) {
                dist[curr - 1] = dist[curr] + 1;
                q.add(curr - 1);
            }

            // Jump right
            if (curr + 1 < n && dist[curr + 1] < 0) {
                dist[curr + 1] = dist[curr] + 1;
                q.add(curr + 1);
            }

            // Jump to all same-value indices
            List<Integer> temp = hmap.get(arr[curr]);
            for (int i = 0; i < temp.size(); i++) {
                if (dist[temp.get(i)] < 0) {
                    dist[temp.get(i)] = dist[curr] + 1;
                    q.add(temp.get(i));
                }
            }
            // Clear to avoid revisiting same-value indices (prevents O(n^2) on duplicates e.g. [2,2,2,2,2])
            temp.clear();
        }

        return dist[n - 1];
    }
}