题目:
给你一个非负整数数组 nums ,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
假设你总是可以到达数组的最后一个位置。
算法:
方法一:dp逆向查找到【数组的最后一个位置】的最少步数
func jump(nums []int) int {
// 保存从index到maxIndex需要的最少步数
minSteps := make([]int, len(nums))
minSteps[len(nums) - 1] = 0
maxIndex := len(nums) - 1
for i := len(nums) - 2; i >= 0; i -- {
if i + nums[i] >= maxIndex {
minSteps[i] = 1
} else {
step := math.MaxInt32
for j := nums[i]; j > 0; j -- {
if 1 + minSteps[i + j] < step {
step = 1 + minSteps[i + j]
}
}
minSteps[i] = step
}
}
// fmt.Println(minSteps)
return minSteps[0]
}
方法二:贪心逆序查找
func jump(nums []int) int {
position := len(nums) - 1
step := 0
for position > 0 {
for i := 0; i < position; i ++ {
if i + nums[i] >= position {
position = i
step ++
continue
}
}
}
return step
}
方法三:贪心算法(精髓)
nums = [2,3,1,1,4],
index=0时,走第一步,最远走到index=2,step ++, 在走到index=2之前,更新rightMost位置。
index++,走到index=2时,第一步走完,走第二步,最远走到index=4
func jump(nums []int) int {
rightMost := 0
step := 0
stepRightMost := 0
for i := 0; i < len(nums) - 1; i ++ {
rightMost = max(rightMost, i + nums[i])
if i == stepRightMost {
stepRightMost = rightMost
step ++
}
}
return step
}
func max(a, b int) int {
if a > b {
return a
}
return b
}