一、第一种实现:

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

/**
* 总人数
*
* @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. PHP Extension开发(Zephir版本)

    上篇介绍了C语言开发PHP扩展的方法, 现在介绍使用Zephir开发扩展的方法. 关于Zephir需要简单介绍一下: Zephir 是为PHP开发人员提供的能够编写可编译/静态类型的高级语言.是优秀的 ...

  2. MySQL数据库基础(四)(子查询与链接)

    1.子查询简介 其中,所谓的"外层查询"并不是指"查找",指的是所有SQL语句的统称:结构化查询语言(Structured Query Language),简称 ...

  3. CentOS命令修改系统时间同步

    使用Centos,遇到本地时间对不上,直接敲命令:date -s "2016-01-08  15:15:15"是立即生效了,但是重启后,系统时间还是原来的. 修改了其一是没有办法奏 ...

  4. Jenkins系列——定时构建

    1.环境说明 操作系统:win7旗舰版64bit jdk:sun JDK1.7.0_80 64bit tomcat:apache-tomcat-8.0.41 jenkins:2.32.3LST 本系列 ...

  5. 4.3 lambda表达式

    函数,封装的代码块可以很复杂,也可以很简单.当函数的代码块简单到只有一个表达式,就可以考虑用lambda表达式,也称匿名函数. 1 lambda表达式基础 #首先需要声明一点:lambda是表达式而非 ...

  6. 历届试题 大臣的旅费 树形DP

    题目链接:大臣的旅费 思路:锦囊说用广搜,可惜这题没说数据范围,担心复杂度太高,我就直接用的树形DP--求树的最远路径. 以城市1为整棵树的根结点,d(i)表示以i为根结点的子树的最远路径,还有一个f ...

  7. 浅谈CDN、SEO、XSS、CSRF

    CDN 什么是CDN 初学Web开发的时候,多多少少都会听过这个名词->CDN. CDN在我没接触之前,它给我的印象是用来优化网络请求的,我第一次用到CDN的时候是在找JS文件时.当时找不到相对 ...

  8. Dockerfile 编译安装mysql5.7 千万不要执行.只是记录一下编译安装罢了

    开启所有核心make  20G 内存都不够玩,跑3-4个核心吧,还好. 最后的出来的镜像3G多,百思不得其解,看了官方的Dockerfile,也没什么特别,就是 apt 或者 yum.好吧,不知做了什 ...

  9. python file文件操作--内置对象open

    说明: 1. 函数功能打开一个文件,返回一个文件读写对象,然后可以对文件进行相应读写操作. 2. file参数表示的需要打开文件的相对路径(当前工作目录)或者一个绝对路径,当传入路径不存在此文件会报错 ...

  10. window下如何使用Git上传代码到github远程服务器上(转)

    注册账户以及创建仓库 首先你得有一个github账号,没有自行注册,登录成功后应该是这样 在页面上方用户菜单上选择 "+"->New repository 创建一个新的仓库 ...