有一个数组a[N]顺序存放0~N-1,要求每隔两个数删掉一个数,到末尾时循环至开头继续进行,求最后一个被删掉的数的原始下标位置。以8个数(N=7)为例:{0,1,2,3,4,5,6,7},0->1->2(删除)->3->4->5(删除)->6->7->0(删除),如此循环直到最后一个数被删除。
输入描述: 每组数据为一行一个整数n(小于等于1000),为数组成员数,如果大于1000,则对a[999]进行计算。
输出描述: 一行输出最后一个被删掉的数的原始下标位置。
输入例子1: 8
输出例子1: 6
CODE:
import java.util.*; public class Main{ public static void main(String [] args){ Scanner sc=new Scanner(System.in); while(sc.hasNext()){ int input=sc.nextInt(); Queue list=new LinkedList(); if(input>1000)input=999; for(int i=0;i<input;i++){ list.offer(i); } while(list.size()!=1){ for(int j=0;j<2;j++){ list.offer(list.poll()); } list.poll(); } System.out.println(list.poll()); } } }
上面的题目其实就是约瑟夫环问题,在剑指offer中有类似的题目。
题目描述--孩子们的游戏(圆圈中最后剩下的数)
每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)
CODE
import java.util.*; public class TEST { // 解法一:思路:每隔m-1个就会删除一个,使用队列,每次将队列前m-2个数弹出并加入队尾,然后删除队头,一次循环。 /** public static int LastRemaining_Solution(int n, int m) { Queue<Integer> queue = new LinkedList<>(); for (int i = 0; i < n; i++){ queue.offer(i); } while (queue.size() != 1){ for (int j = 0; j < m-1; j++){ queue.offer(queue.poll()); } queue.poll(); } return queue.poll(); } */ // 解法二:每次都以上一次的位置为基准,找到要删除的位置 public static int LastRemaining_Solution(int n, int m) { ArrayList<Integer> arrayList = new ArrayList<>(); for (int i = 0; i < n; i++) arrayList.add(i); int index = 0; while (arrayList.size() != 1){ index = (index + m -1) % arrayList.size(); arrayList.remove(index); } return arrayList.get(0); } public static void main(String[] args) { int q = LastRemaining_Solution(5, 3); System.out.println(q); } }