
贪心代码1:
- 反向查找出发位置
- 遍历数组,找到第一个可以跳到目标位置的下标
- 因为我们要找最小下标,所以遍历查找的时候是正向遍历,而目标位置我们是从最终位置开始的,
- 也就是目标反向遍历,查找正向查找
func jump(nums []int) int {
position := len(nums) - 1
steps := 0
for position > 0 {
for i := 0; i < position; i++ {
if i + nums[i] >= position {
position = i
steps++
break
}
}
}
return steps
}
贪心代码2:
- 代码1简单易懂但最坏情况时间复杂度 N 平方
- 但其实我们正向查找,直接找可以到达最远下标,也就是遍历一次就好
- 如下代码
- end为当前可以跳的最远距离,mx为下一步可以跳到最远距离
- i == end , 并非是当前跳到了end,只是我们遍历到end时,我们的mx成功维护了下一步的最远距离,所以此时更新end以及ans
- 因为我们把第 0 步也ans++了所以我们最后一步不再加ans,
- 这样写的好处是,我们将最小的那个临界值一并考虑了,即数组里只有一个值,起点便是终点
func jump(nums []int) int {
ans := 0
end := 0
mx := 0
for i := 0; i < len(nums)-1; i++ {
mx = max(mx, nums[i] + i)
if i == end {
end = mx
ans++
}
}
return ans
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
代码3:
- 此代码也就是代码2的初始版本,
func jump(nums []int) int {
n := len(nums)
if n == 1 {
return 0
}
jumpNums, start, end, maxLen := 1, 1, nums[0], nums[0]
for maxLen < n-1 {
for i := start; i <= end; i++ {
if i + nums[i] > maxLen {
maxLen = i + nums[i]
}
}
jumpNums++
start = end + 1
end = maxLen
}
return jumpNums
}