跳至主要內容

45, 跳跃游戏II

Mike大约 2 分钟greedymediumarraygreedydynamic programming

一、题目描述

给定一个长度为n0索引整数数组nums。初始位置为nums[0]

每个元素nums[i]表示从索引i向前跳转的最大长度。换句话说,如果你在nums[i]处,你可以跳转到任意nums[i + j]处:

  • 0 <= j <= nums[i]
  • i + j < n

返回到达nums[n - 1]的最小跳跃次数。生成的测试用例可以到达nums[n - 1]

示例 1
输入: nums = [2, 3, 1, 1, 4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是2。从下标为0跳到下标为1的位置,跳1步,然后跳3步到达数组的最后一个位置。

示例 2
输入: nums = [2, 3, 0, 1, 4]
输出: 2

提示

  • 1 <= nums.length <= 10⁴
  • 0 <= nums[i] <= 1000
  • 题目保证可以到达nums[n - 1]

相关主题

  • 贪心
  • 数组
  • 动态规划

二、题解

方法 1: 反向遍历查找

pub fn jump(nums: Vec<i32>) -> i32 {
    let mut pos = nums.len() - 1;
    let mut steps = 0;

    while pos != 0 {
        for i in 0..pos {
            if i + nums[i] as usize >= pos {
                pos = i;
                steps += 1;
                break;
            }
        }
    }

    steps
}

方法 2: 贪心

pub fn jump(nums: Vec<i32>) -> i32 {
    let (mut max_pos, len, mut end) = (0, nums.len(), 0);
    let mut steps = 0;

    for i in 0..len - 1 {
        if max_pos >= i {
            max_pos = std::cmp::max(max_pos, i + nums[i] as usize);
            if i == end {
                end = max_pos;
                steps += 1;
            }
        }
    }

    steps
}