zoukankan      html  css  js  c++  java
  • 45. 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.)

    Hide Tags
     Array Greedy 

    链接: http://leetcode.com/problems/jump-game-ii/

    题解:

    在Jump Game基础上还要计算最小jump数,所以除了maxCover外还需要维护一个lastCover。在当前i值超过lastCover所处index时,我们要把steps数加1。在循环结束后再判断是否满足能到达最后一个index,假如可以,返回steps,不可以则返回0。

    Time Complexity - O(n), Space Complexity - O(1)。

    public class Solution {
        public int jump(int[] nums) {
            if(nums == null || nums.length == 0)
                return 0;
            int maxCover = 0, lastCover = 0, steps = 0;
            
            for(int i = 0; i < nums.length && i <= maxCover; i++){
                if(i > lastCover){
                    steps++;
                    lastCover = maxCover;
                }
                if(i + nums[i] > maxCover)
                    maxCover = i + nums[i];
            }
            
            if(maxCover >= nums.length - 1)                
                return steps;
            return 0;
        }
    }

    二刷:

    主要是使用了一种Greedy的思想来求最小步数。

    1. 首先我们设置不满足题意的corner case返回Integer.MAX_VALUE
    2. 接下来设置一个maxCover = 0, lastCover = 0, steps = 0。 maxCover代表我们当前能够到达的最大距离,lastCover等于之前的maxCover,用来记录我们在Greedy情况下每一跳的最远范围。
    3. 从0开始遍历数组,要注意条件是 i <= maxCover && i < nums.length
      1. 假如i > lastCover,这时候说明我们已经超过了之前记录的maxCover的范围,这个时候我们必须要进行一次跳跃,所以steps++,并且我们更新lastCover = maxCover,即上一条之后,我们这一次最远可以跳到哪里
      2. 假如i + nums[i] > maxCover, 这个时候我们更新maxCover = i + nums[i],可以继续进行接下来的计算
    4. 当循环结束时,我们检测maxCover是否 >= nums.length - 1
      1. 假如成立,则说明我们可以到达右边界,这时候返回steps
      2. 否则我们返回Integer.MIN_VALUE

    看了一下discuss,这道题也可以用BFS来做。就是假设现在在0, 我们可以reach到 nums[0],  那我们接下来处理的就是在nums[0]范围内的数字,比如 1 和 2, 然后根据1 和 2的范围再继续找到下一层BFS,最后当范围包括到最后一个节点的时候我们返回这个层数。其实等同于一个非加权图中两点间最短路径问题。但没仔细看代码,复杂度怎么计算还不知道。

    Java:

    Time Complexity - O(n), Space Complexity - O(1)

    public class Solution {
        public int jump(int[] nums) {
            if (nums == null || nums.length == 0) {
                return Integer.MAX_VALUE;
            }
            int maxCover = 0, lastCover = 0, steps = 0;
            for (int i = 0; i <= maxCover && i < nums.length; i++) {
                if (i > lastCover) {
                    lastCover = maxCover;
                    steps++;
                }
                if (i + nums[i] > maxCover) {
                    maxCover = i + nums[i];
                }
            }
            return maxCover >= nums.length - 1 ? steps : Integer.MAX_VALUE;
        }
    }

    三刷:

    方法跟上面一样。另外设置一个lastCover变量,每次当i > lastCover的时候,我们更新steps,并且设置lastCover = maxCover

    Java:

    public class Solution {
        public int jump(int[] nums) {
            if (nums == null || nums.length == 0) return 0;
            int maxCover = 0, lastCover = 0, steps = 0;
            for (int i = 0; i < nums.length && i <= maxCover; i++) {
                if (i > lastCover) {
                    steps++;
                    lastCover = maxCover;
                }
                maxCover = Math.max(maxCover, i + nums[i]);
            }
            return (maxCover >= nums.length - 1) ? steps : Integer.MAX_VALUE;
        }
    }

    update:

    当maxCover >= nums.length - 1时,我们可以跳过后面的计算。  

    public class Solution {
        public int jump(int[] nums) {
            if (nums == null || nums.length == 0) return 0;
            int maxCover = 0, lastCover = 0, steps = 0;
            for (int i = 0; i < nums.length && i <= maxCover; i++) {
                if (i > lastCover) {
                    steps++;
                    lastCover = maxCover;
                }
                maxCover = Math.max(maxCover, i + nums[i]);
                if (maxCover >= nums.length - 1) {
                    if (lastCover >= nums.length - 1) return steps;
                    else return steps + 1;
                }
            }
            return Integer.MAX_VALUE;
        }
    }

    Reference:

    https://leetcode.com/discuss/10588/o-n-bfs-solution

    https://leetcode.com/discuss/13293/sharing-my-ac-java-solution

    https://leetcode.com/discuss/30647/single-loop-simple-java-solution

    https://leetcode.com/discuss/45992/10-lines-c-16ms-python-bfs-solutions-with-explanations

    https://leetcode.com/discuss/67047/concise-o-n-one-loop-java-solution-based-on-greedy

  • 相关阅读:
    JavaScript进阶系列06,事件委托
    JavaScript进阶系列05,事件的执行时机, 使用addEventListener为元素同时注册多个事件,事件参数
    JavaScript进阶系列04,函数参数个数不确定情况下的解决方案
    JavaScript进阶系列03,通过硬编码、工厂模式、构造函数创建JavaScript对象
    JavaScript进阶系列02,函数作为参数以及在数组中的应用
    JavaScript进阶系列01,函数的声明,函数参数,函数闭包
    委托、Lambda表达式、事件系列07,使用EventHandler委托
    委托、Lambda表达式、事件系列06,使用Action实现观察者模式,体验委托和事件的区别
    委托、Lambda表达式、事件系列05,Action委托与闭包
    委托、Lambda表达式、事件系列04,委托链是怎样形成的, 多播委托, 调用委托链方法,委托链异常处理
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4436343.html
Copyright © 2011-2022 走看看