【LeetCode】剑指 Offer 62. 圆圈中最后剩下的数字
【LeetCode】剑指 Offer 62. 圆圈中最后剩下的数字
文章目录
- 【LeetCode】剑指 Offer 62. 圆圈中最后剩下的数字
- 一、动态规划
- 总结
一、动态规划
构建一个长度为 n 的链表,各结点值为对应的顺序索引。每轮删除第 m 个结点,直至链表长度为 1 时结束,返回最后剩余结点的值即可
模拟法需要循环删除 n - 1 轮,每轮在链表中寻找删除结点需要 m 次访问操作(链表线性遍历),因此总体时间复杂度为 O(n*m)。题目给定的 m,n 取值范围,可知此时间复杂度是不可接受的
实际上本题是著名的”约瑟夫环“问题,可用动态规划解决
输入 n,m,记此约瑟夫环问题为 【n,m 问题】,设解(即最后留下的数字)为 f(n),则有:
- 【n,m 问题】:数字环为 0,1,2,…,n - 1,解为 f(n)
- 【n - 1,m 问题】:数字环为 0,1,2,…,n - 2,解为 f(n - 1)
- 以此类推……
数字环是首尾相接的,为了方便行文,本文使用列表形式表示
对于 【n,m 问题】,首轮删除环中第 m 个数字后,得到一个长度为 n - 1 的数字环。由于有可能 m > n,因此删除的数字为 (m - 1) % n,删除后的数字环从下个数字(即 m%n )开始,设 t = m%n,可得数字环:
删除一轮后的数字环也变为一个 【n - 1,m 问题】,观察以下数字编号对应关系:
设 【n - 1,m问题】某数字为 x,则可得递推关系:
换而言之,若已知【n - 1,m 问题】的解 f(n - 1),则可通过以上公式计算得到【n,m 问题】的解 f(n),即:
以 n = 5,m = 3 的示例如下图所示
f(n) 可由 f(n-1) 得到,f(n-1) 可由 f(n-2) 得到,……,f(2) 可由 f(1) 得到。因此,若给定 f(1) 的值,就可以递推至任意 f(n)。而【1,m 问题】的解 f(1) = 0 恒成立,即无论 m 为何值,长度为 1 的数字环留下的数字一定是 0
动态规划解析:
- 状态定义:设【i,m 问题】的解为 dp[i]
- 转移方程:通过以下公式可从 dp[i - 1] 递推得到 dp[i]
- 初始状态:【1,m 问题】的解恒为 0,即为 dp[1] = 0
- 返回值:返回【n,m 问题】的解 dp[n]
下图为 n = 5,m = 3 时的状态转移和对应的模拟删除过程
class Solution {public int lastRemaining(int n, int m) {int x = 0;for(int i = 2; i <=n; i++) x = (x + m) % i;return x;}
}
- 时间复杂度 O(n):状态转移循环 n - 1 次使用 O(n) 时间,状态转移方程计算使用 O(1) 时间
- 空间复杂度 O(1):使用常数大小的额外空间
总结
动态规划还是比较难发现的,看题解之前我根本想不到这是个动态规划题。题解看起来很复杂,但其实难点只有如何求出状态转移方程式,动态规划的思想其实并不难理解,不要被绕进去
【LeetCode】剑指 Offer 62. 圆圈中最后剩下的数字相关推荐
- 90. Leetcode 剑指 Offer 62. 圆圈中最后剩下的数字 (动态规划-基础题)
步骤一.确定状态: 确定dp数组及含义 dp[i]表示的是i个数里面循环删除m个数剩下的数 步骤二.推断状态方程: 首先假设f(n,m)表示从n个数字0....n−1中每次删除第 m个数字之后剩下的数 ...
- java求最后一位不为0的数字_【Java】 剑指offer(62) 圆圈中最后剩下的数字
本文参考自<剑指offer>一书,代码采用Java语言. 题目 0, 1, -, n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字 ...
- 【LeetCode笔记】剑指 Offer 62. 圆圈中最后剩下的数字(Java、约瑟夫环、链表)
文章目录 题目描述 思路 & 代码 链表模拟法 数学方法 二刷 题目描述 约瑟夫环!题目可太经典了 说实话还是有点难度的= = 思路 & 代码 链表模拟法 第一想法是用 LinkedL ...
- 打卡系列-剑指 Offer 62. 圆圈中最后剩下的数字
0,1,,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 例如,0.1.2.3.4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字 ...
- 约瑟夫环的问题--剑指 Offer 62. 圆圈中最后剩下的数字
class Solution {// f(n, m) = (f(n – 1, m) + m) % npublic int lastRemaining(int n, int m) {return (n ...
- 剑指offer:圆圈中最后剩下的数
题目描述 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为牛客的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的:首先,让小朋友们围成一个大圈.然后,他随机指 ...
- 【算法-剑指 Offer】62. 圆圈中最后剩下的数字(环形链表;约瑟夫环;动态规划)
剑指 Offer 62. 圆圈中最后剩下的数字 - 力扣(LeetCode) 发布:2021年9月12日12:18:52 问题描述及示例 0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每 ...
- LeetCode 面试题62. 圆圈中最后剩下的数字 详细题解
面试题62. 圆圈中最后剩下的数字 难度 简单 0,1,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 例如,0.1.2.3.4这5个数 ...
- leetcode 面试题62. 圆圈中最后剩下的数字
面试题62. 圆圈中最后剩下的数字 0,1,,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 例如,0.1.2.3.4这5个数字组成一个 ...
最新文章
- 因主机名更改造成oracle控制台登录错误:ora-12545,ora-12541
- mysql内存不断被占用,导致每隔一个多月就自动重启,修改数据库配置后,问题解决...
- SQL Server:Like 通配符特殊用法:Escape
- Java枚举的内容可以使用map的方式
- Android kotlin基础语法
- 刚copy试探发表了一篇文章文章,oschina感觉良好
- LaTeX设置参考文献条目行距以及条目内行距的方法
- java ioc_Java体验IOC
- 学计算机毁一生,大学中4大“天坑”级别的专业,学了毁一生,家里没钱不要学...
- Objective-C代码学习大纲
- JWT跨域身份验证解决方案
- 联想y7000p不识别耳机,联想y7000插上耳机没有声音
- 纲要-Java网络爬虫系统性学习与实战(1)
- 征集国内操作系统项目列表
- JSON和全局异常处理
- socket网络通信实现与优化
- HTML5~用户注册页面的设计与实现
- 【矿渣】【玩客云】玩客云驱动OLED屏幕
- Linux 命令xxd输出十六进制
- mxgraph进阶(三)Web绘图——mxGraph项目实战(精华篇)
热门文章
- android studio创建一个类继承application_带你全方位了解Android中的Context
- 随机生成元素升序向量_实验二MATLAB运算基础 -
- python都能做什么图_如何学习数据分析
- PyCharm Active Code Generator
- Java并发包——使用新的方式创建线程
- nginx 反向代理之 proxy_redirect
- python简说(十八)导入模块
- 1.9编程基础之顺序查找02:输出最高分数的学生姓名
- java模拟记事本的一些功能
- python 数学公式显示_ipython jupyter notebook中显示图像和数学公式实例