题目:有 n 个人围成一圈,顺序排好。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子, 问最后留下的是原来第几位?
解题:
例如 n = 2, 最后留下来的是2
n = 3, 最后留下来的是2
n = 4, 最后留下来的是1
n = 5, 最后留下来的是4
这个题目,写着写着就有思路了。
package com.jandmin.demo.leetcode;
import com.alibaba.fastjson.JSONObject;
/**
* @description: 求最后剩下的人的序号
* 有 n 个人围成一圈,顺序排好。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,
* 问最后留下的是原来第几号的那位?
* 例如 n = 2, 最后留下来的是2
* n = 3, 最后留下来的是2
* n = 4, 最后留下来的是1
* n = 5, 最后留下来的是4
* @author: JandMin
* @create: 2019-08-09
**/
public class LastRemainderSerial {
public static void main(String[] args) {
int n = 100;
// 初始化第几个数
int[] serials = initSerial(n);
System.out.println(JSONObject.toJSONString(serials));
// 把数到第三个数排除:标记为 0
excludeThird(serials);
System.out.println(JSONObject.toJSONString(serials));
// 最后值不为0的数则是最后的值
int last = getLastSerial(serials);
System.out.println("the last remainder is " + last);
}
/**
* @Description: 获取不为 0 的数
* @Date: 2019/8/9
* @param lastArray 排除第三个后的数组
* @return: int
*/
private static int getLastSerial(int[] lastArray) {
for(int i : lastArray){
if(i != 0){
return i;
}
}
return 0;
}
/**
* @Description: 排除第三个:标记为0
* @Date: 2019/8/9
* @param serials 原始排序数组
* @return: void
*/
private static void excludeThird(int[] serials) {
// 记录剩下的人数
int remainder = serials.length;
int len = remainder;
// 计入开始报数
int start = 0;
// 只保留一个不为不标记 0
while (remainder > 1){
for(int i = 0; i<len; i++){
// 标记为 0 的数过
if(serials[i] == 0){
continue;
}
// 不为 0 则加1
start++;
// 第三个数标记为 0,同时 n 减1,并重新开始计数
if(start == 3){
serials[i] = 0;
remainder--;
start = 0;
continue;
}
}
}
}
/**
* @Description: 初始化排序数组
* @Date: 2019/8/9
* @param n
* @return: int[]
*/
private static int[] initSerial(int n) {
if(n < 1){
return new int[]{1};
}
int[] serials = new int[n];
for (int i=0; i<n; i++){
serials[i] = i + 1;
}
return serials;
}
}