45.跳跃游戏 II

44 阅读1分钟

题目:
给你一个非负整数数组 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
}