`
frank-liu
  • 浏览: 1686166 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

leetcode: Jump Game II

 
阅读更多

问题描述:

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Your goal is to reach the last index in the minimum number of jumps.

For example:
Given array A = [2,3,1,1,4]

The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)

Note:
You can assume that you can always reach the last index.

原问题链接:https://leetcode.com/problems/jump-game-ii/

 

问题分析

初步思路

  因为假定每个步骤都可以走到数组的最后面,于是很容易想到一种思路。就是我们用一个等长的数组来记录到这个位置所走的最小步数。比如上面示例中的数组A = [2, 3, 1, 1 4]。在最开始索引为0的位置,它的长度为2。所以从索引0到索引0 + 2这个位置是它能走的第一步的范围。然后看索引1的值,将它和A[1]的值相加的所有范围的数字尝试比较加一,取其中较小的那个数字。概括起来说,对于任意一个位置i,我们在新建的数组里设置成steps[i + j] = Math.min(steps[i + j], steps[i] + 1),其中j表示从1到A[i]的范围内的取值。

  所以根据上述讨论可以得到如下的代码:

 

public class Solution {
    public int jump(int[] nums) {
        if(nums == null || nums.length <= 1) return 0;
        int n = nums.length;
        int[] steps = new int[n];
        for(int i = 1; i < n; i++) steps[i] = Integer.MAX_VALUE;
        for(int i = 0; i < n; i++) {
            for(int j = 1; j < nums[i] && i + j < n; j++) {
                steps[i + j] = Math.min(steps[i] + 1, steps[i + j]);
            }
        }
        return steps[n - 1];
    }
}

   上述代码需要额外申请一个同等长度的数组空间,另外,里面的for循环在nums[i]值比较大的时候也会产生严重的性能影响。所以它的时间复杂度会达到O(N^2)。在实际的运行时候会导致超时。

 

思路改进

  上述的问题解决思路虽然逻辑上是正确的但是执行效率比较低。因此需要想办法去改进它的执行性能。我们来看有没有别的办法。对于上述的问题,当我们从最开始的索引节点开始取步数的时候,我们最多能覆盖的范围就是A[0]的值所定的范围,如下图:

  假定4是它所能涵盖最远的范围,那么对于1到4这个范围内的值来说,它的最小步数就是1。在没有到达数组的末尾时,我们需要继续考虑步数为2的涵盖范围。在1到4的这个范围内来取,假设中间1所取的数值范围最大,如下图:

  这个时候,我们要取的第二步的范围是从4到9。 通过这个步骤推演,我们会发现一个规律。就是对于任何一个步数来说,它当前所能涵盖的最大范围即为所用步数最少的范围。比如前面到4只需要1步。而从当前步数涵盖的范围到下一个范围则需要从当前范围里取涵盖最大的一个。这样依次类推。

  所以每次我们只要在某个步数所能涵盖的最大范围内设置它当前的步数,只有超过这个最大范围的时候才对这个步数加一。求下一个步数的时候则求在当前步数的范围内能涵盖的最大值。在具体的实现中,我们需要记录在每一步中它所能涵盖的最大值,每次到遍历到这个值的时候,我们的步数加一。另外,我们在每次的遍历中都要计算当前位置所能涵盖的最大范围以作为下一个步数所能涵盖的范围。

  按照这个思路我们能得到如下的代码:

 

public class Solution {
    public int jump(int[] A) {
        int jumps = 0, curEnd = 0, curFarthest = 0;
        for (int i = 0; i < A.length - 1; i++) {
            curFarthest = Math.max(curFarthest, i + A[i]);
            if (i == curEnd) {
                jumps++;
                curEnd = curFarthest;
            }
        }
        return jumps;
    }
}

   这种方法的时间复杂度为O(N),它的性能得到大幅的提升。从本质上来说这是一种贪婪的思路。我们每次都去找当前步数所能涵盖的最大范围。

 

 

  • 大小: 4.7 KB
  • 大小: 9.5 KB
分享到:
评论

相关推荐

    java-leetcode题解之Jump Game II.java

    java java_leetcode题解之Jump Game II.java

    javalruleetcode-LeetCode::lollipop:个人LeetCode习题解答仓库-多语言

    java lru leetcode :ice_cream: LeetCode Kindem 的个人 LeetCode 题解仓库,欢迎交流学习。 下面的目录中 $number 题号代表经典 LeetCode ...LeetCode ...Jump Game 56 Merge Intervals 64 Minimum Path Sum 73

    leetcode71python-leetcode:leetcode

    leetcode 71 Python用 Python 编写 Leetcode (数据科学家的解决方案) - 易于理解的最佳解决方案,可以通过所有 Leetcode 测试用例,对于非 ...Game II (HARD) Leetcode 51. N-Queens (HARD) Leetcode 52. N-

    java-leetcode题解之Jump Game.java

    java java_leetcode题解之Jump Game.java

    leetcode跳跃-leetcode:leetcode

    标题 "leetcode跳跃-leetcode:leetcode" 暗示着这是一个关于LeetCode的编程挑战和学习资源,特别是与解决跳跃游戏(Jump Game)相关的题目。LeetCode是一个在线平台,提供了大量的编程练习题,帮助开发者提高算法...

    leetcode跳跃-leetcode:leetcode一天一次

    Jump Game II - 二叉树 前序遍历判断二叉树:98. Validate Binary Search Tree - 二分查找 二分查找 + 数据缓存:1095. Find in Mountain Array 链表 有序链表合并:21. Merge Two Sorted Lists 回文 双指针判断回文...

    leetcode跳跃-Leetcode:力码

    "跳跃"在这里通常指的是LeetCode中的一个问题——“跳跃游戏”(Jump Game)。这类问题涉及到数组处理和动态规划等算法知识。 【描述】"LeetCode 跳跃 LeetCode" 这个描述虽然简短,但我们可以从中了解到讨论的...

    leetcode跳跃-leetcode:leetcode解题之路

    II](./Array/jump-game-ii.md) [0053 最大子序和](./Array/maximum-subarray.md) [0041 缺失的第一个整数](./Array/first-missing-positive.md) [0042 接雨水](./Array/trapping-rain-water.md) [0048 旋转图像](./...

    gasstationleetcode-leetcode:LeetcodeOJ解决方案

    leetcode 【演示记录】 报告 展示 2017/03/06 1.二和,167.二和二 2107/03/06 15.3 总和,16.3 总和最近,18.4 总和,11.最多水的容器 2017/03/09 62.Unique Paths, 63.Unique Paths II, 64.Minimum Path Sum 2017/...

    leetcode跳跃-LeetCode:力码

    在LeetCode中,有些跳跃问题可能可以通过贪心算法来解决,例如经典的“跳跃游戏”(Jump Game)系列。这类问题通常涉及到数组元素,需要确定在有限步数内能否到达数组的最后一个元素。 具体到“跳跃游戏”,我们...

    leetcode跳跃-leetcode:记录Leetcode刷题思路

    例如经典的“跳跃游戏”(Jump Game),要求在给定数组中,每个元素代表可以跳跃的最大距离,判断能否在限定步数内到达数组最后一个位置。 三、解题策略 1. 动态规划:对于一些有重叠子问题的跳跃题目,动态规划...

    Leetcode:leet码问题

    例如,经典问题"跳跃游戏"(Jump Game)要求判断给定的步长数组,是否存在一种跳跃方式能从头到尾遍历整个数组。 解这类问题时,我们可以尝试以下策略: 1. **广度优先搜索(BFS)**:从数组的第一个元素开始,逐步...

    leetcode:我的leetcode培训。 实践使完美!

    "跳跃游戏"(Jump Game)是一道涉及贪心算法和查找的题目。 7. **动态规划**:解决复杂问题,如斐波那契数列、背包问题等。"最长公共子序列"(Longest Common Subsequence)是一道经典的动态规划题目。 8. **回溯...

    C语言-leetcode题解之45-jump-game-ii.c

    c语言入门 C语言_leetcode题解之45-jump-game-ii.c

    js-leetcode题解之45-jump-game-ii.js

    js js_leetcode题解之45-jump-game-ii.js

    java-leetcode题解之055-Jump-Game

    java入门 java_leetcode题解之055_Jump_Game

    js-leetcode题解之55-jump-game.js

    js js_leetcode题解之55-jump-game.js

    fuxuemingzhu#Leetcode-Solution-All#55. Jump Game 跳跃游戏1

    1.贪心算法中,作出的每步贪心决策都无法改变,因为贪心策略是由上一步的最优解推导下一步的最优解,而上一步之前的最优解则不作保留 2.由(1)中的介绍,可以知道贪

Global site tag (gtag.js) - Google Analytics