【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

动态规划解析:

  1. 状态定义:设【i,m 问题】的解为 dp[i]
  2. 转移方程:通过以下公式可从 dp[i - 1] 递推得到 dp[i]
  3. 初始状态:【1,m 问题】的解恒为 0,即为 dp[1] = 0
  4. 返回值:返回【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. 圆圈中最后剩下的数字相关推荐

  1. 90. Leetcode 剑指 Offer 62. 圆圈中最后剩下的数字 (动态规划-基础题)

    步骤一.确定状态: 确定dp数组及含义 dp[i]表示的是i个数里面循环删除m个数剩下的数 步骤二.推断状态方程: 首先假设f(n,m)表示从n个数字0....n−1中每次删除第 m个数字之后剩下的数 ...

  2. java求最后一位不为0的数字_【Java】 剑指offer(62) 圆圈中最后剩下的数字

    本文参考自<剑指offer>一书,代码采用Java语言. 题目 0, 1, -, n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字 ...

  3. 【LeetCode笔记】剑指 Offer 62. 圆圈中最后剩下的数字(Java、约瑟夫环、链表)

    文章目录 题目描述 思路 & 代码 链表模拟法 数学方法 二刷 题目描述 约瑟夫环!题目可太经典了 说实话还是有点难度的= = 思路 & 代码 链表模拟法 第一想法是用 LinkedL ...

  4. 打卡系列-剑指 Offer 62. 圆圈中最后剩下的数字

    0,1,,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 例如,0.1.2.3.4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字 ...

  5. 约瑟夫环的问题--剑指 Offer 62. 圆圈中最后剩下的数字

    class Solution {// f(n, m) = (f(n – 1, m) + m) % npublic int lastRemaining(int n, int m) {return (n ...

  6. 剑指offer:圆圈中最后剩下的数

    题目描述 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为牛客的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的:首先,让小朋友们围成一个大圈.然后,他随机指 ...

  7. 【算法-剑指 Offer】62. 圆圈中最后剩下的数字(环形链表;约瑟夫环;动态规划)

    剑指 Offer 62. 圆圈中最后剩下的数字 - 力扣(LeetCode) 发布:2021年9月12日12:18:52 问题描述及示例 0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每 ...

  8. LeetCode 面试题62. 圆圈中最后剩下的数字 详细题解

    面试题62. 圆圈中最后剩下的数字 难度 简单 0,1,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 例如,0.1.2.3.4这5个数 ...

  9. leetcode 面试题62. 圆圈中最后剩下的数字

    面试题62. 圆圈中最后剩下的数字 0,1,,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 例如,0.1.2.3.4这5个数字组成一个 ...

最新文章

  1. 因主机名更改造成oracle控制台登录错误:ora-12545,ora-12541
  2. mysql内存不断被占用,导致每隔一个多月就自动重启,修改数据库配置后,问题解决...
  3. SQL Server:Like 通配符特殊用法:Escape
  4. Java枚举的内容可以使用map的方式
  5. Android kotlin基础语法
  6. 刚copy试探发表了一篇文章文章,oschina感觉良好
  7. LaTeX设置参考文献条目行距以及条目内行距的方法
  8. java ioc_Java体验IOC
  9. 学计算机毁一生,大学中4大“天坑”级别的专业,学了毁一生,家里没钱不要学...
  10. Objective-C代码学习大纲
  11. JWT跨域身份验证解决方案
  12. 联想y7000p不识别耳机,联想y7000插上耳机没有声音
  13. 纲要-Java网络爬虫系统性学习与实战(1)
  14. 征集国内操作系统项目列表
  15. JSON和全局异常处理
  16. socket网络通信实现与优化
  17. HTML5~用户注册页面的设计与实现
  18. 【矿渣】【玩客云】玩客云驱动OLED屏幕
  19. Linux 命令xxd输出十六进制
  20. mxgraph进阶(三)Web绘图——mxGraph项目实战(精华篇)

热门文章

  1. android studio创建一个类继承application_带你全方位了解Android中的Context
  2. 随机生成元素升序向量_实验二MATLAB运算基础 -
  3. python都能做什么图_如何学习数据分析
  4. PyCharm Active Code Generator
  5. Java并发包——使用新的方式创建线程
  6. nginx 反向代理之 proxy_redirect
  7. python简说(十八)导入模块
  8. 1.9编程基础之顺序查找02:输出最高分数的学生姓名
  9. java模拟记事本的一些功能
  10. python 数学公式显示_ipython jupyter notebook中显示图像和数学公式实例