leetcode-跳跃游戏 II

409 阅读2分钟

晚上抽出时间,继续做一题leetcode。

题目

给你一个非负整数数组 nums ,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
假设你总是可以到达数组的最后一个位置。

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

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

思路

首先理解一下题意,每个位置的值是可以跳跃的最大长度,但是也可以选择跳的更近,所以并不是最无脑的调到每个格子能跳到的最大的值。
每个格子作为起点,可以跳的距离是一个线段,这个线段上的点,都可以作为下一次起跳的起点,所以我们可以遍历这个线段,当前位置下标+位置上的数值就是一个备选的下一个起跳点,所以当前最优的跳跃到的位置,应该是线段是max(下标+值),然后再遍历下一个可达的线段,直到可以到最后一个点位置,如下图所示

45.jpg

第一个数值是2,所以第1跳可达的线段是[1,2],从1出发,最远可以到达4,从2出发,最远可以到达3,所以第一跳应该选择跳跃到下标1;下一跳备选的起点就有2、3、4,因为4就是最后一个点了,所以可以直接结束,如果不是,那就是遍历这个线段,后面不再赘述。

Java版本代码

class Solution {
    public int jump(int[] nums) {
        int len = nums.length;
        int ans = 0;
        int start = 0;
        int end = 0;
        while (end < len - 1) {
            int farest = 0;
            for (int i = start; i <= end; i++) {
                farest = Math.max(farest, i + nums[i]);
            }
            ans++;
            start = end + 1;
            end = farest;
        }
        return ans;
    }
}