【Java】 剑指offer(62) 圆圈中最后剩下的数字
本文参考自《剑指offer》一书,代码采用Java语言。
题目
0, 1, …, n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。
思路
方法一:采用链表来存放数据,每次对长度取余来实现循环
将所有数字放入LinkedList链表中(LinkedList比ArrayList更适合增删操作)。假设当前删除的结点下标为removeIndex,则下一个要删除的结点的下标为:(removeIndex+m-1)%list.size(),通过取余符号可以实现类型循环的操作。
注:没必要用循环链表,反而会更麻烦了。
方法二:数学推导规律
n个数字的圆圈,不断删除第m个数字,我们把最后剩下的数字记为f(n,m)。
n个数字中第一个被删除的数字是(m-1)%n, 我们记作k,k=(m-1)%n。
那么剩下的n-1个数字就变成了:0,1,……k-1,k+1,……,n-1,我们把下一轮第一个数字排在最前面,并且将这个长度为n-1的数组映射到0~n-2。
原始数字:k+1,……, n-1, 0, 1,……k-1
映射数字:0 ,……,n-k-2, n-k-1, n-k,……n-2
把映射数字记为x,原始数字记为y,那么映射数字变回原始数字的公式为 y=(x+k+1)%n。
在映射数字中,n-1个数字,不断删除第m个数字,由定义可以知道,最后剩下的数字为f(n-1,m)。我们把它变回原始数字,由上一个公式可以得到最后剩下的原始数字是(f(n-1,m)+k+1)%n,而这个数字就是也就是一开始我们标记为的f(n,m),所以可以推得递归公式如下:
f(n,m) =(f(n-1,m)+k+1)%n
将k=(m-1)%n代入,化简得到:
f(n,m) =(f(n-1,m)+m)%n
f(1,m) = 0
代码中可以采用循环或者递归的方法实现该递归公式。时间复杂度为O(n),空间复杂度为O(1)。
测试算例
1.功能测试(m大于/小于/等于n)
2.特殊测试(n、m<=0)
3.性能测试(n=4000,n=997)
Java代码
//题目:0, 1, …, n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里
//删除第m个数字。求出这个圆圈里剩下的最后一个数字。 public class LastNumberInCircle {
/*
* 方法一:采用推导出来的方法
*/
public int LastRemaining_Solution(int n, int m) {
if(n<1 || m<1)
return -1; //出错
int last=0;
for(int i=2;i<=n;i++){
last=(last+m)% i; //这里是i不是n!!!
}
return last;
} /*
* 方法二:采用链表来存放,每次对长度取余来实现循环
*/
public int LastRemaining_Solution2(int n, int m) {
if(n<1 || m<1)
return -1; //出错
LinkedList<Integer> list = new LinkedList<Integer>();
for(int i=0;i<n;i++)
list.add(i);
int removeIndex=0;
while(list.size()>1){
removeIndex=(removeIndex+m-1)%list.size();
list.remove(removeIndex);
}
return list.getFirst();
}
}
收获
1.对于下标循环一圈类似的问题,通过%可以很好地实现循环,而不需要我们自己构造循环链表;
2.(a%n+b)%n=(a+b)%n
3.尽量学会本题的数学方法,特别是要掌握好数字间映射的方法。
4.公式法中,last=(last+m)% i; //这里是i不是n!!!
【Java】 剑指offer(62) 圆圈中最后剩下的数字的更多相关文章
- 剑指 Offer 62. 圆圈中最后剩下的数字 + 约瑟夫环问题
剑指 Offer 62. 圆圈中最后剩下的数字 Offer_62 题目描述 方法一:使用链表模拟 这种方法是暴力方法,时间复杂度为O(nm),在本题中数据量过大会超时. 方法二:递归方法 packag ...
- [剑指offer]62.圆圈中最后剩下的数字
62.圆圈中最后剩下的数字 题目 0,1,...,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 例如,0.1.2.3.4这5个数字组成 ...
- 【剑指offer】圆圈中最后剩下的数字(约瑟夫问题),C++实现
原创博文,转载请注明出处! # 题目 # 思路 本题即为典型的约瑟夫问题,通过递推公式倒推出问题的解.原始问题是从n个人中每隔m个数踢出一个人,原始问题变成从n-1个人中每隔m个数踢出一个人-- ...
- 剑指offer——72圆圈中最后剩下的数字
题目描述 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为牛客的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的:首先,让小朋友们围成一个大圈.然后,他随机指 ...
- 剑指offer46:圆圈中最后剩下的数字(链表,递归)
1 题目描述 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为牛客的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的:首先,让小朋友们围成一个大圈.然后,他随 ...
- Java实现 LeetCode 面试题62. 圆圈中最后剩下的数字(约瑟夫环)
面试题62. 圆圈中最后剩下的数字 0,1,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 例如,0.1.2.3.4这5个数字组成一个圆 ...
- 【LeetCode】面试题62. 圆圈中最后剩下的数字
题目:面试题62. 圆圈中最后剩下的数字 这题很有意思,也很巧妙,故记录下来. 官方题解思路,是约瑟夫环的数学解法: 我们将上述问题建模为函数 f(n, m),该函数的返回值为最终留下的元素的序号. ...
- 《剑指offer》面试题62. 圆圈中最后剩下的数字
问题描述 0,1,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 例如,0.1.2.3.4这5个数字组成一个圆圈,从数字0开始每次删除第 ...
- [LeetCode]面试题62. 圆圈中最后剩下的数字(数学)
题目 0,1,,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 例如,0.1.2.3.4这5个数字组成一个圆圈,从数字0开始每次删除第3 ...
随机推荐
- 第一节 简单的jsp实例
1.打开Eclipse,依次点击“File” .“New” .“Other” ,选择生成动态Web项目. 2.输入项目名字,点击Finish 生成项目结构如下: 3.在WebContent目录上,单击 ...
- 20155237 2016-2017-2 《Java程序设计》第8周学习总结
20155237 2016-2017-2 <Java程序设计>第8周学习总结 教材学习内容总结 NIO与NIO2 认识NIO Channel: 衔接数据节点(与IO中的流对比) isOpe ...
- Docker入门02——Dockerfile详解
基本示例 FROM MAINTAINER LABEL RUN ADD COPY CMD ENTRYPOINT ENV EXPOSE VOLUME WORKDIR USER ARG 基本示例 # Thi ...
- 树形控件QTreeWidget
import sys from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QApplication, QWidget, QTreeWidge ...
- [C++]埃拉托色尼算法
/* 埃拉托色尼算法 问题描述:定义一个正整数n,求0-n范围以内的所有质数 @date 2017-03-06 @author Johnny Zen */ #include<iost ...
- cpp与其他语言相比较
new 相当于 malloc ,delete 相当于 free ,用法一样 c++ 有 namespace,可以避免类名污染 namespace xx{} c++ 有类 这个与 c#.as3比较 ...
- Android学习笔记——Content Provider(一)
Content Provider是Android系统四大组件之一: 官方的定义是:A Content Provider manages access to a central repository o ...
- 【通信】Jave代码中生成url http请求
/** * 向指定 URL 发送POST方法的请求 * * @param url * 发送请求的 URL * @param param * 请求参数,请求参数应该是 name1=value1& ...
- Spring+Struts+Mybatis+Shiro整合配置
Jar包
- 【Linux】VMware虚拟机中如何配置静态IP
此处详解如何在VMware虚拟机中配置静态IP. 上图是一个草图,大致说明下VMware网络情况.网段指某个IP范围,例如一栋小区楼和另一栋小区楼就不是一个网段 如果你在A小区,你女朋友在B小区,你想 ...