2022-08-10:为了给刷题的同学一些奖励,力扣团队引入了一个弹簧游戏机,
游戏机由 N 个特殊弹簧排成一排,编号为 0 到 N-1,
初始有一个小球在编号 0 的弹簧处。若小球在编号为 i 的弹簧处,
通过按动弹簧,可以选择把小球向右弹射 jump[i] 的距离,或者向左弹射到任意左侧弹簧的位置,
也就是说,在编号为 i 弹簧处按动弹簧,
小球可以弹向 0 到 i-1 中任意弹簧或者 i+jump[i] 的弹簧(若 i+jump[i]>=N ,则表示小球弹出了机器),
小球位于编号 0 处的弹簧时不能再向左弹。
为了获得奖励,你需要将小球弹出机器。
请求出最少需要按动多少次弹簧,可以将小球从编号 0 弹簧弹出整个机器,即向右越过编号 N-1 的弹簧。

答案2022-08-10:

宽度优先遍历。Index Tree。
时间复杂度:O(N*logN)。

代码用rust编写。代码如下:

fn main() {
let mut jump1: Vec<i32> = vec![2, 5, 1, 1, 1, 1];
let mut jump2 = jump1.clone();
let ans1 = min_jump(&mut jump1);
let ans2 = min_jump2(&mut jump2);
println!("ans1 = {}", ans1);
println!("ans2 = {}", ans2);
} // 宽度优先遍历
// N*logN
fn min_jump(jump: &mut Vec<i32>) -> i32 {
let n = jump.len() as i32;
let mut queue: Vec<i32> = vec![];
for _ in 0..n {
queue.push(0);
}
let mut l: i32 = 0;
let mut r: i32 = 0;
queue[r as usize] = 0;
r += 1;
let mut it = IndexTree::new(n);
// 1...n初始化的时候 每个位置填上1
for i in 1..n {
it.add(i, 1);
}
let mut step: i32 = 0;
while l != r {
// 队列里面还有东西
// tmp记录了当前层的终止位置!
let tmp = r;
// 当前层的所有节点,都去遍历!
while l < tmp {
let cur = queue[l as usize];
let forward = cur + jump[cur as usize];
if forward >= n {
return step + 1;
}
if it.value(forward) != 0 {
queue[r as usize] = forward;
r += 1;
it.add(forward, -1);
}
// cur
// 1....cur-1 cur
while it.sum(cur - 1) != 0 {
let find0 = find(&mut it, cur - 1);
it.add(find0, -1);
queue[r as usize] = find0;
r += 1;
}
l += 1;
}
step += 1;
}
return -1;
} fn find(it: &mut IndexTree, mut right: i32) -> i32 {
let mut left = 0;
let mut mid;
let mut find0 = 0;
while left <= right {
mid = (left + right) / 2;
if it.sum(mid) > 0 {
find0 = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return find0;
} pub struct IndexTree {
tree: Vec<i32>,
n: i32,
} impl IndexTree {
pub fn new(size: i32) -> Self {
let mut tree: Vec<i32> = vec![];
for _ in 0..size + 1 {
tree.push(0);
}
Self { tree, n: size }
} pub fn value(&mut self, index: i32) -> i32 {
if index == 0 {
return self.sum(0);
} else {
return self.sum(index) - self.sum(index - 1);
}
} pub fn sum(&mut self, i: i32) -> i32 {
let mut index = i + 1;
let mut ret = 0;
while index > 0 {
ret += self.tree[index as usize];
index -= index & -index;
}
return ret;
} pub fn add(&mut self, i: i32, d: i32) {
let mut index = i + 1;
while index <= self.n {
self.tree[index as usize] += d;
index += index & -index;
}
}
} // 感谢黄汀同学
// 弄出了时间复杂度O(N)的过程
// 和大厂刷题班,第10节,jump game类似
fn min_jump2(jump: &mut Vec<i32>) -> i32 {
let nn = jump.len() as i32;
let mut ans = nn;
let mut next = jump[0];
if next >= nn {
return 1;
}
if next + jump[next as usize] >= nn {
return 2;
}
// dp[i] : 来到i位置,最少跳几步?
let mut dp: Vec<i32> = vec![];
for _ in 0..nn + 1 {
dp.push(nn);
}
// dis[i] : <= i步的情况下,最远能跳到哪?
let mut dis: Vec<i32> = vec![];
for _ in 0..nn {
dis.push(0);
}
// 如果从0开始向前跳,<=1步的情况下,最远当然能到next
dis[1] = next;
// 如果从0开始向前跳,<=2步的情况下,最远可能比next + jump[next]要远,
// 这里先设置,以后可能更新
dis[2] = next + jump[next as usize];
dp[(next + jump[next as usize]) as usize] = 2;
let mut step = 1;
for i in 1..nn {
if i > dis[step as usize] {
step += 1;
}
dp[i as usize] = get_min(dp[i as usize], step + 1);
next = i + jump[i as usize];
if next >= nn {
ans = get_min(ans, dp[i as usize] + 1);
} else if dp[next as usize] > dp[i as usize] + 1 {
dp[next as usize] = dp[i as usize] + 1;
dis[dp[next as usize] as usize] = get_max(dis[dp[next as usize] as usize], next);
}
}
return ans;
} fn get_max<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a > b {
a
} else {
b
}
} fn get_min<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a < b {
a
} else {
b
}
}

执行结果如下:


左神java代码

2022-08-10:为了给刷题的同学一些奖励,力扣团队引入了一个弹簧游戏机, 游戏机由 N 个特殊弹簧排成一排,编号为 0 到 N-1, 初始有一个小球在编号 0 的弹簧处。若小球在编号为 i 的弹的更多相关文章

  1. 【刷题】BZOJ 3527 [Zjoi2014]力

    Description 给出n个数qi,给出Fj的定义如下: 令Ei=Fi/qi,求Ei. Input 第一行一个整数n. 接下来n行每行输入一个数,第i行表示qi. n≤100000,0<qi ...

  2. LeetCode刷题总结-数组篇(下)

    本期讲O(n)类型问题,共14题.3道简单题,9道中等题,2道困难题.数组篇共归纳总结了50题,本篇是数组篇的最后一篇.其他三个篇章可参考: LeetCode刷题总结-数组篇(上),子数组问题(共17 ...

  3. leetcode每日刷题计划-简单篇day3

    收到swe提前批面试hhh算是ep挂了的后续 努力刷题呀争取今年冲进去! Num 21 合并两个有序链表 Merge Two Sorted Lists 注意新开的链表用来输出结果的是ListNode ...

  4. C#LeetCode刷题-字典树

    字典树篇 # 题名 刷题 通过率 难度 208 实现 Trie (前缀树)   48.6% 中等 211 添加与搜索单词 - 数据结构设计   39.9% 中等 212 单词搜索 II   27.9% ...

  5. C#LeetCode刷题-数组

    数组篇 # 题名 刷题 通过率 难度 1 两数之和 C#LeetCode刷题之#1-两数之和(Two Sum) 43.1% 简单 4 两个排序数组的中位数 C#LeetCode刷题之#4-两个排序数组 ...

  6. USACO刷题之路,开始了

    几天前,重新开始刷题了. 重新刷题有几个原因: 1.曾经的OI经历,如今除了悟性高些.知识多些,大多已经遗忘.不希望真的让之前的OI水平就这么丢了. 2.越来越觉得,刷题真的是一件很开心的事情.大学中 ...

  7. 杭电acm刷题(3):1062,Text Reverse 标签: 杭电acm 2017-05-15 08:26 126人阅读 评论(0)

    Problem Description Ignatius likes to write words in reverse way. Given a single line of text which ...

  8. LeetCode刷题笔记 - 2022

    这篇博客集中整理在LeetCode的刷题记录,方便查阅 258. 各位相加 - 力扣(LeetCode) (leetcode-cn.com) 代码 class Solution { public: i ...

  9. 好像leeceode题目我的博客太长了,需要重新建立一个. leecode刷题第二个

    376. Wiggle Subsequence               自己没想出来,看了别人的分析. 主要是要分析出升序降序只跟临近的2个决定.虽然直觉上不是这样. 455. 分发饼干     ...

  10. 18.9.10 LeetCode刷题笔记

    本人算法还是比较菜的,因此大部分在刷基础题,高手勿喷 选择Python进行刷题,因为坑少,所以不太想用CPP: 1.买股票的最佳时期2 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. ...

随机推荐

  1. 通过cpolar内网穿透 https://blog.csdn.net/CpolarLisa/article/details/128148698

    远程办公:通过cpolar内网穿透,远程桌面控制家里公司内网电脑_Cpolar Lisa的博客-CSDN博客 https://blog.csdn.net/CpolarLisa/article/deta ...

  2. python实例1(石头 剪刀 布)

    #random   .randint       模块导入 import random #定义一个用户需要输入的数据内容入口 user = int(input("请输入(石头1,剪刀2,布3 ...

  3. DB2通过java代码生成自定义uuid()函数

    一.简单的方法 此种方法在快速大量生成时,会有重复 SELECT concat (hex (RAND ()), hex (RAND ())) as uuid FROM SYSIBM.SYSDUMMY1 ...

  4. 钉钉获取第三方token时提示签名时间戳参数超时的处理方法

    今天在更新平台功能时,碰到一个问题,从钉钉跳转到平台,始终不能成功.查看日志发现,出现了 签名时间戳参数超时 的错误. 想着没有动过相对应的代码,应该不是代码的问题. 查询官方文档,没有给出明确的答复 ...

  5. Python基础教程:字典

    字典 = {'键1':'值1','键2':'值2','键3':'值3',...} animal_dict = {'Cow':'Milk','Chicken':'egg'} 字典由键值对构成,这种键值对 ...

  6. salesforce零基础学习(一百一十四)Dynamic related list

    本篇参考: https://help.salesforce.com/s/articleView?id=release-notes.rn_forcecom_lab_dynamic_related_lis ...

  7. JVM Dump分析

    Thread Dump介绍 Thread Dump是非常有用的诊断 Java应用问题的工具.每一个 Java虚拟机都有及时生成所有线程在某一点状态的 thread-dump的能力,虽然各个 Java虚 ...

  8. Chronicle Pro - 一款简单 Mac 理财规划师,管理你的的个人预算

    使用Chronicle追踪和支付账单,管理你的个人预算,这是一款简单的Mac理财规划师.获得通知,这样你就不会错过下一个付款截止日期;你再也不用付滞纳金了.把你所有的账单放在一起,计划.检查和分析它们 ...

  9. PHP微信三方平台-微信支付(扫码支付)

    1.官方文档地址: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1 2.逻辑分析: 生成支付二维码->用户扫码支付-& ...

  10. 浅谈Array --JavaScript内置对象

    Array --JavaScript内置对象 描述 可以用一个变量存储多种数据类型的Array对象,Array不是关联数组,不能使用字符串作为索引访问数组元素,需要使用非负整数的下标访问数组中的元素. ...