You are given a 0-indexed integer array nums of length n. You are initially standing at index 0. You can jump from index i to index j where i < j if:
nums[i] <= nums[j] and nums[k] < nums[i] for all indexes k in the range i < k < j, or
nums[i] > nums[j] and nums[k] >= nums[i] for all indexes k in the range i < k < j.
You are also given an integer array costs of length n where costs[i] denotes the cost of jumping to index i.
Return the minimum cost to jump to the index n - 1.
Example 1:
Input: nums = [3,2,4,4,1], costs = [3,7,6,4,2]
Output: 8
Explanation: You start at index 0.
- Jump to index 2 with a cost of costs[2] = 6.
- Jump to index 4 with a cost of costs[4] = 2.
The total cost is 8. It can be proven that 8 is the minimum cost needed.
Two other possible paths are from index 0 -> 1 -> 4 and index 0 -> 2 -> 3 -> 4.
These have a total cost of 9 and 12, respectively.
Example 2:
Input: nums = [0,1,2], costs = [1,1,1]
Output: 2
Explanation: Start at index 0.
- Jump to index 1 with a cost of costs[1] = 1.
- Jump to index 2 with a cost of costs[2] = 1.
The total cost is 2. Note that you cannot jump directly from index 0 to index 2 because nums[0] <= nums[1].
Constraints:
n == nums.length == costs.length
1 <= n <= 105
0 <= nums[i], costs[i] <= 105
Solutions
Solution 1: Monotonic Stack + Dynamic Programming
Thinking
From \(i\) we may jump to the next index that is \(\ge nums[i]\) or the next that is \(< nums[i]\), and we want the minimum cost to the end. Scanning right from every \(i\) is too slow. Those two successors are exactly what monotonic stacks compute in linear time.
Build \(g[i]\) with an increasing stack and a non-increasing stack from the right, then relax \(f[j] = \min(f[j], f[i]+costs[j])\) in index order. There are \(O(n)\) edges.
According to the problem description, we need to find the next position \(j\) where \(\textit{nums}[j]\) is greater than or equal to \(\textit{nums}[i]\), and the next position \(j\) where \(\textit{nums}[j]\) is less than \(\textit{nums}[i]\). We can use a monotonic stack to find these two positions in \(O(n)\) time, and then construct an adjacency list \(g\), where \(g[i]\) represents the indices that index \(i\) can jump to.
Then we use dynamic programming to find the minimum cost. Let \(f[i]\) represent the minimum cost to jump to index \(i\). Initially, \(f[0] = 0\) and the rest \(f[i] = \infty\). We enumerate the indices \(i\) from small to large. For each \(i\), we enumerate each index \(j\) in \(g[i]\) and perform the state transition \(f[j] = \min(f[j], f[i] + \textit{costs}[j])\). The answer is \(f[n - 1]\).
The time complexity is \(O(n)\), and the space complexity is \(O(n)\). Here, \(n\) is the length of the array.