持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情
动态规划(Dynamic Programming)是一种分阶段求解决策问题的数学思想,它通过把原问题分解为简单的子问题来解决复杂问题。
跳跃游戏 II
给你一个非负整数数组 nums ,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
假设你总是可以到达数组的最后一个位置。
示例 1:
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。 从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
示例 2:
输入: nums = [2,3,0,1,4]
输出: 2
思路:
定义dp[i]为跳到下标 i 所需的最小跳跃次数,那么dp[nums.length-1]就是所求结果,如何让这个值最小呢,只需要在下标 i 位置前面找到一个下标 j ,它既可以跳到下标i,而且dp[j]最小,然后dp[i]=dp[j]+1。
由于一开始就在下标0,所以dp[0]=0。
代码如下:
fun jump(nums: IntArray): Int {
val length = nums.size
val dp = IntArray(length)
Arrays.fill(dp, Int.MAX_VALUE)
dp[0] = 0
for (i in 0 until length) {
for (j in 0 until i) {
if (j + nums[j] >= i) {//1
dp[i] = Math.min(dp[j] + 1, dp[i])//2
}
}
}
return dp[length - 1]
}
- 注释1位置是为了保证从下标j可以跳转到下标i。
- 注释2位置是因为可能有多个下标都可以跳转到i位置,我们只需要找到最小的跳跃次数即可。
复杂度分析
- 时间复杂度:O(n2),n 是数组长度。有两层嵌套循环。
- 空间复杂度:O(n),申请了dp数组。