博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
leetcode45. Jump Game II
阅读量:5816 次
发布时间:2019-06-18

本文共 2529 字,大约阅读时间需要 8 分钟。

题目要求

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.

对于类似体型Jump Game I,请参考。

这题相对于I,差别在于已知一定可以到达终点,找到一条最短路径所需要的步数。

思路一:递归 超时

通过递归的方式找到一条到达终点的路径。通过和当前最短路径比较来省去一些不必要的遍历。但是存在缺点。其实同一个节点到达最终节点的最短步数是一定的,而每一次递归都造成无法省略的重复遍历。

public int jump(int[] nums) {        jump(nums, 0, 0);        return minimumSteps;    }        public void jump(int[] nums, int currentStep, int currentIndex){        if(currentIndex + nums[currentIndex] >= nums.length){            minimumSteps = Math.min(minimumSteps, currentStep+1);            return;        }        if(minimumSteps!=0 && currentStep >= minimumSteps){            return;        }        for(int i = 1; i<=nums[currentIndex] ; i++){            jump(nums, currentStep+1, currentIndex+i);        }    }

思路二:反向动态编程 超时

如果我们从终点往起点寻找,先找可以直接到达终点的最小下标,然后将该下标作为终点,继续查找到达该终点的最小下标,并将step加一。这种代码在大多数情况下,效率正常,但是如果出现极端情况,比如数据量很大,且到达当前终点的最小下标即为当前终点的前一个节点。就会造成非常严重的无用遍历。在最好的情况下的时间复杂度为O(n),但是最差的时间复杂度为O(n^2)

public int jump2(int[] nums){        int minimumSteps = 0;        int last = nums.length - 1;        while(last != 0){            int nextLast = last;            for(int i =last-1 ; i>=0 ; i--){                if(nums[i] + i >= last){                    nextLast = i;                }            }            last = nextLast;            minimumSteps++;        }                return minimumSteps;    }

思路三:BFS 广度优先算法

再回到正序遍历,举个例子,输入的数组为[2,3,1,1,4],这时候我们知道0步时的下标为0,1步可以走到的下标包括1,2,2步可以走到的下标为3,4,而4即为我们的终点。

转换为广度优先算法即为:

2   step 031  step 114  step 2

我们只需要找到每一步的开始节点和结束下标,找到下一轮遍历的最大下标,如果该下标超过了数组长度,那么结束遍历,返回步数,否则将上一轮的最终节点加一作为起始节点,并将下一轮最大下标最为结束节点,继续遍历。

public int jump3(int[] nums){        int length = nums.length ;         if(length<2) return 0;        int currentMax = 0, i = 0, nextMax = 0, level = 0;;        while(currentMax-i+1 > 0){            level++;            for( ; i <= currentMax ; i++){                nextMax = Math.max(nextMax, nums[i]+i);                if(nextMax>=length-1) return level;            }            currentMax = nextMax;        }        //说明无法到达终点        return nextMax>=length-1? level : -1;    }

clipboard.png

想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注我的微信公众号!将会不定期的发放福利哦~

转载地址:http://ldqbx.baihongyu.com/

你可能感兴趣的文章
Furure的简单介绍和使用
查看>>
CSS3 网格布局(grid layout)基础知识 - 隐式网格自己主动布局(grid-auto-rows/grid-auto-columns/grid-auto-flow)...
查看>>
构建Docker Compose服务堆栈
查看>>
最小角回归 LARS算法包的用法以及模型参数的选择(R语言 )
查看>>
CentOS7下zip解压和unzip压缩文件
查看>>
Hadoop生态圈-Kafka常用命令总结
查看>>
如何基于Redis Replication设计并实现Redis-replicator?
查看>>
Linux 环境下 PHP 扩展的编译与安装 以 mysqli 为例
查看>>
TPS和QPS的区别和理解
查看>>
web前端相关的书籍
查看>>
php防止会话固定攻击
查看>>
openmp在图像处理上面的运用
查看>>
Key Components and Internals of Spring Boot Framework--转
查看>>
基于Bootstrap的jQuery开关按钮插件
查看>>
Python实现代码统计工具——终极加速篇
查看>>
修改linux文件权限命令:chmod
查看>>
如何删除PHP数组中的元素,并且索引重排(unset,array_splice)?
查看>>
网站架构演变
查看>>
Angular学习笔记(三) - 父子组件通信 @Input 与 @OutInput 详解 ( 下 )
查看>>
PAT A1098 堆排序
查看>>