问题:n个人手拉手围城一圈, 从第一个人开始数,数到3该小人退出,问最后剩下的人原来排在第几个位置。
方法1:传统的数组法
public class Count3Quit {
public static void main(String[] args) {
// 假设有500个人
boolean[] arr = new boolean[500];
// 初始化都为true
for (int i = 0; i < arr.length; i++) {
arr[i] = true;
}
int leftCount = arr.length;// 数到圈里只剩一个人结束
int countNum = 0;// 模拟一个计数器
int index = 0;// 从第0个人第0个位置开始数
// 当剩余人数大于1 就不断的进行循环
while (leftCount > 1) {
if (arr[index] == true) {
countNum++;// 如果在圈里开始数并+1
if (countNum == 3) {// 当数到3
countNum = 0; // 重新数
arr[index] = false;
leftCount--;
}
}
index++;
if (index == arr.length) {// 判断数组是否越界
index = 0;// 重新开始数
}
}
for (int i = 0; i < arr.length; i++) {
if (arr[i] == true) {
System.out.println(i);
System.out.println("是第" + (i + 1) + "个人");
}
}
}
}
方法2 面向对象思维
public class Count3Quit2 {
public static void main(String[] args) {
KidCircle kc = new KidCircle(500);
int countNum = 0;
Kid k = kc.first;
while (kc.count > 1) {
countNum++;
if (countNum == 3) {
countNum = 0;
kc.delete(k);
}
k = k.right;
}
System.out.println(kc.first.id);
}
}
class Kid {
int id;// 每个人的编号
Kid left;// 人的左边也是一个人
Kid right;// 右边也是一个人
}
class KidCircle {
int count = 0;// 圈里多少小孩
Kid first, last;// 开头和结束的小孩
KidCircle(int n) {// 构造方法,一个多少小孩的圈
for (int i = 0; i < n; i++) {
add();
}
}
void add() {// 添加小孩
Kid k = new Kid();
k.id = count;
if (count <= 0) {// 如果圈里只有一个小孩
first = k;
last = k;
k.left = k;
k.right = k;
} else {
last.right = k;
k.left = last;
k.right = first;
first.left = k;
last = k;// 新添加的小孩为最后一个
}
count++;
}
// 删除小孩
void delete(Kid k) {
if (count <= 0) {
return;
} else if (count == 1) {
first = last = null;
} else {
k.left.right = k.right;
k.right.left = k.left;
if (k == first) {
first = k.right;
} else if (k == last) {
last = k.left;
}
}
count--;
}
}
后记:昨天某国企的综合面试其中的一道算法题,之前我看到过这个题目,有印象,但当时就是想不起来,其实静下心来分析,题目也不难,可惜当时没有答上来。今天一天也没有收到电话,可能就这样错过了一个很好的机会,这只能怪自己没有认真的准备。
机会总是留给那些有准备的人。期待,加油。