656. Coin Path
Difficulty: Hard
Topics: Dynamic Programming
Similar Questions:
Problem:
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: []
Note:
- Path Pa1, Pa2, ..., Pan is lexicographically smaller than Pb1, Pb2, ..., Pbm, if and only if at the first
i
where Pai and Pbi differ, Pai < Pbi; when no suchi
exists, thenn
<m
. - A1 >= 0. A2, ..., AN (if exist) will in the range of [-1, 100].
- Length of A is in the range of [1, 1000].
- B is in the range of [1, 100].
Solutions:
class Solution {
public:
vector<int> cheapestJump(vector<int>& A, int B) { // reverse order to get lexical smaller result
int n = A.size();
if (n == 0) return {};
if (A[0] == -1 || A[n-1] == -1) return {}; // this check is essential if we reverse the order of A
reverse(A.begin(), A.end());
vector<int> dp(n, INT_MAX);
vector<int> prev(n, 0);
dp[0] = A[0];
prev[0] = -1;
for (int i= 1; i < n; ++i) {
if (A[i] == -1) continue;
for (int j = -1; j >= -B; --j) {
if (i + j < 0) break;
if (dp[i+j] < dp[i]) {
dp[i] = dp[i+j];
prev[i] = i + j;
}
}
if (dp[i] != INT_MAX)
dp[i] += A[i];
}
vector<int> ret;
int i = n - 1;
while (i >= 0 && dp[i] != INT_MAX) {
ret.push_back(n - i);
i = prev[i];
}
if (i >= 0) return {};
return ret;
}
};