顺瓜摸藤解法

题目描述

[45. 跳跃游戏 II]

给你一个非负整数数组 nums ,你最初位于数组的第一个位置。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

你的目标是使用最少的跳跃次数到达数组的最后一个位置。

假设你总是可以到达数组的最后一个位置。  

示例 1:

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

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

提示:

1 <= nums.length <= 104 0 <= nums[i] <= 1000

题解

此题到手,我一时没想到思路,不过做算法题,永远要相信一点的就是:思路比做题重要!

首先要想到一种方案,能讲得通的方案,然后再根据这个方案去实现算法,这样才会有方向,否则就像一只无头苍蝇在窗户上乱撞,也找不到出口。 这题的最重要的一句就是:假设你总是可以到达数据的最后一个位置。那这句的意思就是:假如我站的索引位置i,可以用当前数据num[i]或者当前数据num[i]以下的次数跳出去,就算成功了。这句用开发语言表达出来就是:

var l = num.length
if(i+num[i] >= l)
game is over ! biu biu biu
复制代码

此时问题又来了,到这一步我是结束了,问题我是走了多少步才到这里的呢?也就是这是一个倒推的算法,首先想到了最后的一个结果状态,然后再根据这个成功的状态去反推前面的过程,这就是顺瓜摸藤的解法思路。不过这不是学名,学名应该叫贪心算法,找到一个局部最优解,然后实现破局。

前面我们已经有了一个最后一步的算法,现在反过来想,既然最后一步已经安排好了,我们是不是可以不考虑最后一步了,直接把后面的掐掉,考虑前面的那部分,思路跟这个一样,也是先找最后一步,这样一步步推上去,就把步数算出来了。

好了,思路我已经分析好了,具体写法就按照思路来,中间肯定会遇到问题,多试几次就出来了。

直接上代码吧,掐后面不用真的掐,只有设卡点就好了,然后注意索引不要错位,细节在自己写的时候自己体会吧!

/**
 * @param {number[]} nums
 * @return {number}
 */
var jump = function(nums) {
    var position = nums.length - 1;
    var steps = 0;
    while (position > 0) {
        for (var i = 0; i < position; i++) {
            if (i + nums[i] >= position) {
                position = i;
                steps++;
                break;
            }
        }
    }
    return steps
};
复制代码

复杂度分析

  • 时间复杂度:O(n²),还好,大部分情况下n会掉的比较快
  • 空间复杂度: O(1)

题目来源

猜你喜欢

转载自juejin.im/post/7130636332942475300
今日推荐