Coin Path

This page explains Java solution to problem Coin Path using Dynamic Programming algorithm.

Problem Statement

Given an array A (index starts at 1) consisting of N integers: A1, A2, ..., AN and an integer B. The integer B denotes that from any place (suppose the index is i) in the array A, you can jump to any one of the place in the array A indexed i+1, i+2, …, i+B if this place can be jumped to. Also, if you step on the index i, you have to pay Ai coins. If Ai is -1, it means you can’t jump to the place indexed i in the array.

Now, you start from the place indexed 1 in the array A, and your aim is to reach the place indexed N using the minimum coins. You need to return the path of indexes (starting from 1 to N) in the array you should take to get to the place indexed N using minimum coins.

If there are multiple paths with the same cost, return the lexicographically smallest such path.

If it's not possible to reach the place indexed N then you need to return an empty array.

Example 1:

Input: [1,2,4,-1,2], 2
Output: [1,3,5]

Example 2:

Input: [1,2,4,-1,2], 1
Output: []

Solution

If you have any suggestions in below code, please create a pull request by clicking here.

package com.vc.hard;

import java.util.*;

class CoinPath {
    public List<Integer> cheapestJump(int[] A, int B) {
        if(A == null || A.length == 0 || A[A.length - 1] == -1) return new ArrayList<>();

        int n = A.length;
        int[] dp = new int[n];
        int[] prev = new int[n];
        int[] lexi = new int[n];
        Arrays.fill(prev, -1);
        Arrays.fill(dp, Integer.MAX_VALUE);
        dp[0] = A[0];
        for(int i = 1; i < n; i++) {
            if(A[i] == -1) continue;
            for(int j = Math.max(0, i - B); j < i; j++) {
                if(dp[j] != Integer.MAX_VALUE &&
                        (dp[j] + A[i] < dp[i] || dp[j] + A[i] == dp[i] && lexi[i] < lexi[j] + 1)) {
                    dp[i] = dp[j] + A[i];
                    prev[i] = j;
                    lexi[i] = lexi[j] + 1;
                }
            }
        }

        List<Integer> list = new LinkedList<>();
        for(int i = n - 1; i >= 0; i = prev[i]) {
            list.add(0, i + 1);
        }
        if(list.get(0) != 1) list.clear();
        return list;
    }
}

Time Complexity

O(N * B) Where
N is total number of elements in an input array
B is Max Jump you can take

Space Complexity

O(N) Where
N is total number of elements in an input array