leetcode-55. Jump Game - Medium

descrition

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.

Determine if you are able to reach the last index.

For example:
A = [2,3,1,1,4], return true. A = [3,2,1,0,4], return false.

解析

这是一道动态规划的题,官网有很详细的解答leetcode-solution

动态规划算法的设计步骤:

  1. 递归回溯求解(自顶向下)
  2. 使用记忆回溯法求解 (自顶向下的动态规划)
  3. 去掉递归,使用自底向上的动态规划
  4. 进一步使用技巧优化自底向上的动态规划

根据以上步骤得到以下的解决方法。代码只给出最有解,其他可参考官网的 solution。

方法 1 :

回溯法,recursive(vector& nums, int icur)

  • 如果 icur == nums.size() - 1,到达最后一个位置,递归的出口,表示可以到达最后,返回 true。
  • 递归:i, 1+icur <= i <= min(icur+nums[icur], n-1)

即对每一种情况都递归检查一遍。

时间复杂度-O(2^n); 空间复杂度-O(n),递归需要额外的空间。

方法 2

实际上就是在方法 1 的基础上系上一个 memory 数组,表示当前访问下标 icur 的状态,这样可以避免重复计算。

递归函数可以定义为:recursive(vector& nums, int icur, vector& memory)

时间复杂度-O(n^2),n 个元素,没个元素最多有 n 种可能;空间复杂度-O(n),递归需要额外空间。

方法 3

方法 1 和 方法 2 在对每一步进行试探时从近到远。还可以考虑从远到近进行检查,即每次都从可能到大的最远处进行检查。这种方法的时间复杂度并没有优化,但是从实践的角度可以进行一定的优化。

方法 4

动态规划方法。假设数组 dp[i] 表示位置 i 的状态:UNKONW, GOOD, BAD,分别表示未知,可达,不可达状态。

那么对于任意位置 i ,检查所有的 j = [i+1, min(i+nums[i], n-1)] 的状态,只要有一个 dp[j] = GOOD,则说明 dp[i] 也是 GOOD。边界条件 dp[n-1] = GOOD。

最后我们只需要检查 dp[0] 是否等于 GOOD 即可。

方法 5

对动态规划的进一步优化。核心思想贪心。我们可以从两个角度来看。最优解,时间复杂度-O(n),空间复杂度-O(1)。

1. 从右往左遍历

令 lastPos 表示当前可以到达的最靠近左边的位置。从右边往左边遍历:for(int i=n-1; i>=0, i--)

对任意 i,最远可到达的位置为 farthest = i + nums[i],如果 farthest >= lastPos,则说明从当前位置可以到达最尾的位置,此时更新 lastPos = i 。

最后检查 lastPos 是否为 0 即可。

2. 从左往右遍历

令 farthest 表示能到达的最远距离,我们从左往右遍历:for(int i=0; i<n; i++)。直观来说就是我们每次都往前移动一步,如果 i > farthest 则说明不可能到达最尾节点,直接返回 false。循环中每次都更新 farthest = max(i+nums[i], farthest)。

如果循环能顺利结束,则说明可以到达最尾节点。

code

#include <iostream>
#include <vector>
#include <algorithm> using namespace std; class Solution{
public:
bool canJump(vector<int>& nums){
//return canJumpRight2Left(nums);
return canJumpLeft2Right(nums);
} bool canJumpRight2Left(vector<int>& nums){
int lastPos = nums.size() - 1;
for(int i=nums.size()-1; i>=0; i--){
if((i + nums[i]) >= lastPos){
lastPos = i;
}
}
return lastPos == 0;
} bool canJumpLeft2Right(vector<int>& nums){
int farthest = 0;
for(int i=0; i<nums.size(); i++){
if( i > farthest)
return false;
farthest = max(i + nums[i], farthest);
} return true;
}
}; int main()
{
return 0;
}

[array] leetcode-55. Jump Game - Medium的更多相关文章

  1. [LeetCode] 55. Jump Game_ Medium tag: Dynamic Programming

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

  2. Leetcode 55. Jump Game & 45. Jump Game II

    55. Jump Game Description Given an array of non-negative integers, you are initially positioned at t ...

  3. [array] leetcode - 48. Rotate Image - Medium

    leetcode - 48. Rotate Image - Medium descrition You are given an n x n 2D matrix representing an ima ...

  4. [array] leetcode - 39. Combination Sum - Medium

    leetcode - 39. Combination Sum - Medium descrition Given a set of candidate numbers (C) (without dup ...

  5. [array] leetcode - 31. Next Permutation - Medium

    leetcode - 31. Next Permutation - Medium descrition Implement next permutation, which rearranges num ...

  6. leetcode 55. Jump Game、45. Jump Game II(贪心)

    55. Jump Game 第一种方法: 只要找到一个方式可以到达,那当前位置就是可以到达的,所以可以break class Solution { public: bool canJump(vecto ...

  7. LeetCode: 55. Jump Game(Medium)

    1. 原题链接 https://leetcode.com/problems/jump-game/description/ 2. 题目要求 给定一个整型数组,数组中没有负数.从第一个元素开始,每个元素的 ...

  8. [leetcode] 55. Jump Game (Medium)

    原题 题目意思即 每一格代表你当前最多能再往后跳几次,从第一格开始,如果能跳到最后一格返回true,反之为false. 思路:用一个下标记录当前最多能跳到哪一格,遍历一遍 --> 如果当前格子不 ...

  9. [LeetCode] 55. Jump Game 跳跃游戏

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

  10. Jump Game 的三种思路 - leetcode 55. Jump Game

    Jump Game 是一道有意思的题目.题意很简单,给你一个数组,数组的每个元素表示你能前进的最大步数,最开始时你在第一个元素所在的位置,之后你可以前进,问能不能到达最后一个元素位置. 比如: A = ...

随机推荐

  1. linux服务器使用yum安装nginx

    一,安装nginx和php-fpm yum install nginx php-fpm 二, 找到nginx.conf find / -name nginx.conf 三,添加解析php配置 在ser ...

  2. Python 单向链表、双向链表

    用面向对象实现Linkedlist链表 单向链表实现append.iternodes 双向链表实现append.pop.insert.remove.iternodes 单向链表与双向链表 单向链表: ...

  3. Python [习题] 字典扁平化

    习题: 将以下字典扁平化,输出为 target 字典格式source = {'a': {'b': 1, 'c': 2}, 'd': {'e': 3, 'f': {'g': 4}}}target = { ...

  4. Fedora 23建立wifi热点(Android手机可用)

    在ubuntu14.04下使用ap-hotspot,速度还不错.但是在15.04下就用不了了,不知为啥.现在使用fedora23,在学校还是挺需要给手机连wifi的,于是google看看ap-hots ...

  5. angular2.x指令

    1.指令 *ngIf: 判断 isActive 为true时 <user-detail> 生效展示 <user-detail *ngIf="isActive"&g ...

  6. 自己动手写Redis客户端(C#实现)4 - 整数回复

    整数回复 整数回复就是一个以 ":" 开头, CRLF 结尾的字符串表示的整数. 比如说, ":0\r\n" 和 ":1000\r\n" 都 ...

  7. Server SQL2008对文件的基础操作(1)

    1.一个文件的基本框架为:文件名.文件地址.文件大小.文件最大的大小.文件的增量(Filegrowth). 2.文件有mdf.ndf.ldf 三种文件的区别. 3.文件组可以进行文件的管理 FileG ...

  8. RBAC(Role-Based Access Control,基于角色的权限访问控制)—权限管理设计

    RBAC模型的核心是在用户和权限之间引入了角色的概念,将用户和权限进行解耦,采用用户确定角色,角色分配权限,进而间接达到给用户分配角色的目的 这样采用的方式优点在于 (1)降低管理成本--由于一个角色 ...

  9. 2017最新PHP经典面试题目汇总(上篇)

    1.双引号和单引号的区别 双引号解释变量,单引号不解释变量 双引号里插入单引号,其中单引号里如果有变量的话,变量解释 双引号的变量名后面必须要有一个非数字.字母.下划线的特殊字符,或者用{}讲变量括起 ...

  10. [Docker基础]Docker安装教程

    Install Docker Docker支持几乎所有的Linux发行版,也支持Mac和Windows. 各操作系统的安装方法可参考Docker官网. 安装环境 ubuntu 16.04 Docker ...