leetcode 55. 跳跃游戏 及 45. 跳跃游戏 II
55. 跳跃游戏
问题描述
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
输入: [2,3,1,1,4]
输出: true
解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
示例 2:
输入: [3,2,1,0,4]
输出: false
解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。
代码1(回溯法)
class Solution {
public:
bool canJump(vector<int>& nums) {
int n = nums.size();
return Jump(nums,0,n);
}
bool Jump(vector<int>& nums,int position,int n)
{
if(position == n-1)return true;
else if(position > n-1)return false;
int furthermove = min(n-1,position+nums[position]);
//for(int i = position+1; i <= furthermove; i++)
for(int i = furthermove; i > position; --i)
{
if(Jump(nums,i,n))return true;
}
return false;
}
};
但是该方法在74/75测试用例超出时间限制。
代码2(剪枝回溯/自顶向下)
class Solution {
public:
bool canJump(vector<int>& nums) {
int n = nums.size();
vector<int> flag;
flag.resize(n,-1);
flag[n-1] = 1;
return Jump(nums,0,n,flag);
}
bool Jump(vector<int>& nums,int position,int n,vector<int>& flag)
{
if(flag[position] == 1){
return true;
}
else if(flag[position] == 0) return false;
int furthermove = min(n-1,position+nums[position]);
//for(int i = position+1; i <= furthermove; i++)
for(int i = furthermove; i > position; --i)
{
if(Jump(nums,i,n,flag))
{
flag[i] = 1;
return true;
}
}
flag[position] = 0;
return false;
}
};
但遗憾的是该方法在74/75测试用例仍然超出时间限制。
代码3(自底向上)
class Solution {
public:
bool canJump(vector<int>& nums) {
int n = nums.size(),i,j;
vector<int> flag;
flag.resize(n,-1);
flag[n-1] = 1;
for(i = n-2; i > -1; --i)
{
int furthermove = min(n-1,i + nums[i]);
for(j = i+1; j <= furthermove; ++j)
{
if(flag[j] == 1)
{
flag[i] = 1;
break;
}
}
}
return flag[0] == 1;
}
};
结果仍然不是很理想:
执行用时 :696 ms, 在所有 C++ 提交中击败了13.81%的用户
内存消耗 :15 MB, 在所有 C++ 提交中击败了5.04%的用户
代码4(贪心法)
用贪心来做,设置变量furthermove表示当前所能达到的最远的位置,那么状态转移方程为furthermove = max(furthermove, nums[i] + i),括号里的furthermove是上一步的最优解,因此是贪心。当到了某一个点 i>furthermove 的时候,说明已经走不到这一点了。
class Solution {
public:
bool canJump(vector<int>& nums) {
int n = nums.size(),i,furthermove = nums[0];
for(i = 1; i < n && i<= furthermove; ++i)
{
// if(i <= furthermove)
furthermove = max(furthermove,i+nums[i]);
}
return furthermove>=n-1;
}
};
结果:
执行用时 :16 ms, 在所有 C++ 提交中击败了34.84%的用户
内存消耗 :14.7 MB, 在所有 C++ 提交中击败了5.04%的用户
45. 跳跃游戏 II
问题描述
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
示例:
输入: [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
说明:
假设你总是可以到达数组的最后一个位置。
问题分析
- 1、如果某一个作为 起跳点 的格子可以跳跃的距离是 3,那么表示后面 3 个格子都可以作为 起跳点;可以对每一个能作为 起跳点 的格子都尝试跳一次,把 能跳到最远的距离furthermove 不断更新。
- 2、首先从第0个元素开始,边界end是0,可以跳到的最远距离2,可以跳到1(i =1,furthermove就是4),也可以跳到2(i= 2,furthermove就是3),但是只有两个选择,贪心算法的要素就是获取当前阶段最优解;显然应该跳到1,此时边界end是4。遍历数组的时候,到了边界,我们就重新更新新的边界。
- 3、如果furthermove的值大于等于len-1,那么就可以一直跳到最后,就成功了。
代码
class Solution {
public:
int jump(vector<int>& nums) {
int n = nums.size(),i,furthermove=0,end=0,step=0;
if(n == 1)return 0;
for(i = 0; i < n; i++)
{
furthermove = max(furthermove,nums[i]+i);
if(furthermove>=n-1)return ++step;
if(i == end)
{
end = furthermove;
++step;
}
}
return step;
}
};
问题分析:
执行用时 :12 ms, 在所有 C++ 提交中击败了73.08%的用户
内存消耗 :15.3 MB, 在所有 C++ 提交中击败了5.09%的用户
leetcode 55. 跳跃游戏 及 45. 跳跃游戏 II的更多相关文章
- leetcode 55. Jump Game、45. Jump Game II(贪心)
55. Jump Game 第一种方法: 只要找到一个方式可以到达,那当前位置就是可以到达的,所以可以break class Solution { public: bool canJump(vecto ...
- 55 Jump Game i && 45 Jump Game ii
Jump Game Problem statement: Given an array of non-negative integers, you are initially positioned a ...
- [LeetCode] 45. Jump Game II 跳跃游戏 II
Given an array of non-negative integers, you are initially positioned at the first index of the arra ...
- LeetCode 45. 跳跃游戏 II | Python
45. 跳跃游戏 II 题目来源:https://leetcode-cn.com/problems/jump-game-ii 题目 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素 ...
- 力扣Leetcode 45. 跳跃游戏 II - 贪心思想
这题是 55.跳跃游戏的升级版 力扣Leetcode 55. 跳跃游戏 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 你的目标是使用最少的跳跃 ...
- Java实现 LeetCode 45 跳跃游戏 II(二)
45. 跳跃游戏 II 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后一个位置. 示例: 输入: [ ...
- [leetcode] 45. 跳跃游戏 II(Java)(动态规划)
45. 跳跃游戏 II 动态规划 此题可以倒着想. 看示例: [2,3,1,1,4] 我们从后往前推,对于第4个数1,跳一次 对于第3个数1,显然只能跳到第4个数上,那么从第3个数开始跳到最后需要两次 ...
- [Leetcode]44.跳跃游戏Ⅰ&&45.跳跃游戏Ⅱ
跳跃游戏链接 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示例 1: 输入: [2,3,1,1,4] 输出 ...
- Unity 2D游戏开发教程之游戏中精灵的跳跃状态
Unity 2D游戏开发教程之游戏中精灵的跳跃状态 精灵的跳跃状态 为了让游戏中的精灵有更大的活动范围,上一节为游戏场景添加了多个地面,于是精灵可以从高的地面移动到低的地面处,如图2-14所示.但是却 ...
随机推荐
- 这样学习ZooKeeper离大厂所需技能要求还远吗
概述 定义 Apache ZooKeeper是一种用于构建分布式应用的高性能.高度可靠.开源的分布式协调服务,提供如配置信息维护.命名.分布式同步.组服务等功能,可以实现如分布式共识.组管理.领导选举 ...
- CF1514A Perfectly Imperfect Array 题解
Content 给定一个长度为 \(n\) 的序列,问是否存在一个非空子序列,使得这个子序列所有元素的积不是完全平方数. 数据范围:\(t\) 组数据,\(1\leqslant t\leqslant ...
- java 网络编程基础 TCP/IP协议:服务端ServerSocket;客户端Socket; 采用多线程方式处理网络请求
1.Java中客户端和服务器端通信的简单实例 Java中能接收其他通信实体连接请求的类是ServerSocket,ServerSocket对象用于监听来自客户端的Socket连接,如果没有连接,它将一 ...
- wget 用法http://www.cnblogs.com/cy-8593/p/9523035.html
http://www.cnblogs.com/cy-8593/p/9523035.html
- react 创建项目 sass router redux
创建项目第一步 基本搭建 在创建之前,需要有一个git 仓库,我们要把项目搭建到git 中 目录介绍 cd 到某个盘 mkdir workspace 创建workspace文件夹 cd works ...
- cmake以源码的方式引入第三方项目
最前 本文将介绍一种以源码的方式引入第三方库的方法 准备 主项目,需要引用第三方库的某些函数 第三方库,以源码的形式提供给主项目使用 注意: 本文的背景:已经将第三方源码下载好. 一个例子 我这里准备 ...
- window11连接局域网共享失败处理办法
第一步1.按 Win + R 组合键,打开运行,并输入:gpedit.msc 命令,确定或回车,可以快速打开本地组策略编辑器2.本地组策略编辑器窗口中,依次展开到:计算机配置 - 管理模板 - 网络 ...
- 去除input标签点击时的默认样式
去除input标签点击时的默认样式的方法 outline:none; //去除点击时的边框 border : none; //去除input框的边框
- Python基础入门(8)- Python模块和包
1.包与模块的定义与导入 1.1.什么是python的包与模块 包就是文件夹,包中还可以有包,也就是子文件夹 一个个python文件模块 1.2.包的身份证 __init__.py是每一个python ...
- Spring Boot 2 中的默认日志管理与 Logback 配置详解
Spring Boot在所有内部日志中使用Commons Logging,但是对底层日志的实现是开放的.在Spring Boot生态中,为Java Util Logging .Log4J2 和Logb ...