遇3问题(Java实现)
记录一个笔试题。
问题场景:
有N个人围成一圈,从第一个人开始报数,从 1 报到 3,报到3的人出列,依次循环下去知道最后只剩下一个人,求这个人在原队列中的位置。要求从键盘输入N,输出即为最后剩下那人的位置。
例:
输入:5,输出:4
输入:3,输出:2
下面是代码实现,这里我分别用来两种方法实现,一种是利用栈,一种是使用了类似桶排序的方法。
1、利用栈
import java.util.Scanner;
import java.util.Stack;
public class Main {
static int loop=0;
public static void main(String[] args) {
long time1=System.currentTimeMillis();
Scanner scanner=new Scanner(System.in);
int n;
Stack<Integer> stack1=new Stack<>();
Stack<Integer> stack2=new Stack<>();
n=scanner.nextInt();
for(int i=n;i>0;i--){
stack1.push(i);
}
int total=0;
while(stack1.size()!=1){
if(stack2.size()==0){
total=stack1.size();
for(int i=1;i<=total;i++){
loop++;
if(loop%3==0){
stack1.pop();
}else{
stack2.push(stack1.pop());
}
}
}
if(stack1.size()==0){
total=stack2.size();
for(int i=1;i<=total;i++){
stack1.push(stack2.pop());
}
}
}
System.out.println(stack1.pop());
long time2=System.currentTimeMillis();
System.out.println(time2-time1);
}
}
2、利用桶排序
import java.util.Scanner;
public class To3 {
public static void main(String[] args){
long time1=System.currentTimeMillis();
int[] a;
int n;
Scanner scanner=new Scanner(System.in);
n=scanner.nextInt();
a=new int[n+1];
for(int i=1;i<=n;i++)
a[i]=1;
int i=1,num=0,flag=0;
while(flag!=n-1)
{
if(a[i]==1)
num++;
if(num==3)
{
a[i]=0;
num=0;
flag++;
}
if(i==n)
{
i=0;
}
i++;
}
for(int j=1; j<=n; j++)
{
if(a[j]==1)
System.out.println(j);
}
long time2=System.currentTimeMillis();
System.out.println(time2-time1);
}
}
从所耗时间上来看,第二种方法效率更高,并且在N的大小逐渐增大的情况下,第二种方法的效率会比第一种好很多。
将第二种算法改用C/C++实现的话,应该运行速度还能提升不少,有兴趣的可以尝试一下。
吾生也有涯,而知也无涯。