java面试数量级面试题_[Java] 关于一道面试题的思考

文中的速度测试部分,时间是通过简单的 System.currentTimeMillis() 计算得到的,

又由于 Java 的特性,每次测试的结果都不一定相同,

对于低数量级的情况有 ± 20 的浮动,对于高数量级的情况有的能有 ± 1000 的浮动。

这道题本质上是个约瑟夫环问题,最佳解法在最下面,本文只是探究一下数组暴力和链表的表现差异。

题目

N 个人围成一圈,顺序排号。从第一个人开始报数(从1数到3),凡是到3的人退出圈子,问最后留下的是原来第几号。

样例

2 个人时留下的是第二个;

3个人时留下的是第二个;

5个人时留下的是第四个;

12个人时留下的是第十个;

100,000个人时留下的是第92620个人。

机器环境

CPU Intel Xeon E3-1231 v3 @ 3.40GHz

RAM 16 GB

暴力解决

虽然第一反应是用链表,但对于人数在1000以下的量级感觉数组也足以胜任,因此先用数组试试。

对于这种会 退出 的情况,数组显然不能像链表一样直接断开,因此采用标记法:

先生成一个长度为 N 的布尔型数组,用 true 填充。

报号时,对于报到 3 的位置,用 false 来标记该位置,下次循环如果遇到 false 则可以直接跳过。

那么等到数组内只剩一个 true 的时候,找到其位置,即是最后留下来的人的位置。

既然暴力,那干脆彻底一点:

public static int findIndex(final int N) {

boolean[] map = new boolean[N];

Arrays.fill(map, true);

int walk = 1;

// 因为是站成一个圆,所以在遍历到最后时需要将下标重新指向 0

// count(map) 就是遍历整个数组计算还剩余的 true 的数量

for (int index = 0; count(map) > 1; index = (index == N - 1) ? 0 : (index + 1)) {

// 对于 false 可以直接跳过,因为它们相当于不存在

if (! map[index]) continue;

// 报号时如果不是3 则继续找下一位;

if (walk++ != 3) continue;

// 如果是 3,则重置报号,并将当前位置的值改为 false

walk &

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值