一、第一种实现:

实现比较简单,直接贴现成的代码了,第一种实现:

/**
* 总人数
*
* @param d
*/
private static void sortQuerry1(int d) {
// TODO 先构造一个数组
ArrayList<Integer> arr = new ArrayList<>();
for (int i = 1; i <= d; i++) {
arr.add(i);
}
int xiabiao = -1;
int count = 0;
// 循环查找
int mun = 10;
while (arr.size() > 1) {
xiabiao++;
count++;
if (count == 3) {
System.out.println("移除的是" + arr.get(xiabiao));
arr.remove(xiabiao);
count = 0;
xiabiao = xiabiao - 1;
}
if (xiabiao == (arr.size() - 1)) {
xiabiao = -1;
}
if (arr.size() == 1) {
System.out.println("最后一个剩余的人是:" + arr.get(0));
break;
} } }

二、优化和改进

思考1分钟,上述这种实现的缺点是什么?

时间到了,答案就在Arraylist上面,Arraylist.remove()方法的实现原理是将数组第i个元素之后的所有元素,向前挪一位,这样会导致时间复杂度增加。

如何改进呢?尽量避免ArrayList.remove()方法的使用。下面是一种实现:

private static void sortQuerry2(int d) {
// TODO 先构造一个数组
ArrayList<Boolean> arr = new ArrayList<>(); for (int i = 1; i <= d; i++) {
arr.add(true);
}
int xiabiao = -1;
int count = 0;
int x=0;
// 循环查找
while (true) { xiabiao++;
if(xiabiao>=arr.size()-1)
xiabiao=xiabiao%arr.size();
if(arr.get(xiabiao)==false)
continue;
if (x>=arr.size()-1) {
System.out.println("最后一个剩余的人是:" + (xiabiao+1));
break;
}
count++;
if (count == 3) {
System.out.println("移除的是" + (xiabiao+1));
arr.set(xiabiao, false);
count = 0;
x++;
System.out.println("X是" + x); }
if (xiabiao == (arr.size() - 1)) {
xiabiao = -1;
} }
}

三、测试对比:

两组数据分别是200000,400000

public static void main(String[] args) {
System.out.println("请输入一个数字:");//200000,400000
Scanner scanner = new Scanner(System.in);
int d = scanner.nextInt();
long startTime=System.currentTimeMillis();
sortQuerry1(d);
long endTime=System.currentTimeMillis();
System.out.println("消耗时间:"+(endTime-startTime)/1000.000); }

第一组测试数据200000:

sortQuerry1耗时: 3.919     sortQuerry2耗时:3.304

第二组测试数据400000:

sortQuerry1耗时: 13.443     sortQuerry2耗时:7.157

当数据量大的时候,算法二明显要快于算法1。

以上欢迎交流。

某厂java算法题实现及改进【有n个人成一圈,顺序排号(编号为1到n),从第一个人开始报数1到3报数】的更多相关文章

  1. 【转】约瑟夫环算法---------题目:有n个人围成一圈,顺序排号,从第一个开始报数(从1到3报数),凡报到3的人退出圈子,问最后最后留下的是原来第几号的那位.

    提示:用环形链表实现 对于这个题目其实就是用c语言的循环链表实现一个约瑟夫环.我们可以定义一个循环链表,将这n个人加入到链表中,然后定义三个节点指针在链表上循环,移动跨度为3,利用链表的循环功能每次删 ...

  2. java例题_37 有 n 个人围成一圈,顺序排号。从第一个人开始报数(从 1 到 3 报数),凡报到 3 的人退出圈子, 3 问最后留下的是原来第几号的那位。

    1 /*37 [程序 37 报数] 2 题目:有 n 个人围成一圈,顺序排号.从第一个人开始报数(从 1 到 3 报数),凡报到 3 的人退出圈子, 3 问最后留下的是原来第几号的那位. 4 */ 5 ...

  3. 一道java算法题分析

    最近在面试中遇到这样的一道算法题:       求100!的结果的各位数之和为多少?       如:5!=5*4*3*2*1=120,那么他们的和为1+2+0=3这道题不算难,不过倒是注意的细节也有 ...

  4. 面试-java算法题

    1.编写一个程序,输入n,求n!(用递归的方式实现). public static long fac(int n){ if(n<=0) return 0; else if(n==1) retur ...

  5. 【JAVA算法题】职业抢劫

    题目 /*You are a professional robber planning to rob houses along a street. * Each house has a certain ...

  6. 25道经典Java算法题

    题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?   //这是一个菲波拉契数列问题 [Java] 纯 ...

  7. 50道java算法题(一)

    [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程序分析:   兔子的规律为数列1 ...

  8. 趣味Java算法题(附答案)

    [程序1]    题目:古典问题:有一对兔子,从出生后第3个月起每一个月都生一对兔子,小兔子长到第三个月后每一个月又生一对兔子,假如兔子都不死,问每一个月的兔子总数为多少?    //这是一个菲波拉契 ...

  9. 面试题-JAVA算法题

    1.编写一个程序,输入n,求n!(用递归的方式实现). public static long fac(int n){ if(n<=0) return 0; else if(n==1) retur ...

随机推荐

  1. 【技术干货】git常用命令

    2.1 git init语法: git init在当前目录初始化git仓库,适用于尚未使用git管理的项目2.2 git clone语法: git clone <url>例如: git c ...

  2. navcat无法远程连接mysql数据库解决办法

    navcat无法远程连接mysql数据库,一般都是因为本地ip没有访问权限,服务器上执行下面指令即可解决 mysql -u root -p GRANT ALL PRIVILEGES ON *.* TO ...

  3. mybatis like条件添加%的方法

    使用 MySQL可以使用CONCAT函数.例: <if test="userName != null and userName != ''"> and user_nam ...

  4. Halcon一日一练:图像拼接技术

    图像拼接技术就是针对同一场景的一系列图片,根据图片的特征,比如位置,重叠部分等,拼接成一张大幅的宽视角的图像. 图像拼接要求拼接后图像最大程度的与原图一致,失真尽可能的小,并且要尽量做到天衣无缝即没有 ...

  5. 第十九章 Django的ORM映射机制

    第十九章 Django的ORM映射机制 第一课 Django获取多个数据以及文件上传 1.获取多选的结果(checkbox,select/option)时: req.POST.getlist('fav ...

  6. WEB开发-动态验证码

    1.基于Python实现,用到了django后台处理,刷新验证码功能,其他语言大同小异 2.登录界面 login.html <!DOCTYPE html> <html lang=&q ...

  7. asp.net动态网站repeater控件使用及分页操作介绍

    asp.net动态网站repeater控件使用及分页操作介绍 1.简单介绍 Repeater 控件是一个容器控件,可用于从网页的任何可用数据中创建自定义列表.Repeater 控件没有自己内置的呈现功 ...

  8. 2_成员函数(Member Functions)

    成员函数以定从属于类,不能独立存在,这是它与普通函数的重要区别.所以我们在类定义体外定义成员函数的时候,必须在函数名之前冠以类名,如Date::isLeapYear().但如果在类定义体内定义成员函数 ...

  9. Android 插件化方案(动态加载)总结

    1.作用 大多数Android开发人员开始接触这个问题是因为 App 爆棚了,方法数超过了一个 Dex 最大方法数 65535 的上限,因而便有了插件化的概念,将一个 App 划分为多个插件(Apk ...

  10. [php错误]PHP中Notice: unserialize(): Error at offset of bytes in on line 的解决方法

    使用unserialize函数将数据储存到数据库的时候遇到了这个报错, 后来发现是将gb2312转换成utf-8格式之后, 每个中文的字节数从2个增加到3个之后导致了反序列化的时候判断字符长度出现了问 ...