约瑟夫环-猴子选大王(变型题)
接着上篇猴子选大王继续展开,上篇讲的是有m个猴子,从第一个猴子开始报数,当报到n时,第n个猴子出去,从n+1猴子开始,从1继续报数。
这篇我们来说,从任意猴子k的位置开始报数,当报到n时,第n个猴子出去,从n+1猴子开始,从1继续报数
问题描述:
约瑟夫环运作如下:
1、一群猴子围在一起坐成环状(如:N)
2、从某个编号开始报数(如:K)
3、数到某个数(如:M)的时候,此猴出列,下一个猴子重新报数
4、一直循环,直到所有猴子出列,约瑟夫环结束,同时输出最后的大王。
解题思路:
我们还是用循环链表解决,这里有两种方法,一种是根据上篇讲的那样,构造循环链表,利用循环操作将头指针指向第k个结点上,后续操作和上篇一样
代码如下:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入猴子数N: ");
int n = sc.nextInt();
System.out.println("请输入开始报数编号K: ");
int k = sc.nextInt();
System.out.println("请输入出列数M: ");
int m = sc.nextInt();
if(k > n || m > n) {
System.out.println("编号K或者M不能大于猴子总数N");
System.exit(0);
}
ListNode head = createListNode(n);
while(k != 1){
head = head.next;
k--;
}
int count = 1;
ListNode pre = null;
while(head.next != head){
pre = head;
head = head.next;
count++;
if(count == m){
System.out.println("当前出局人是: "+ head.val);
pre.next = head.next;
head = pre.next;
count = 1;
}
}
System.out.println("最后的大王是: "+ head.val);
}
public static ListNode createListNode(int m){
ListNode head = new ListNode(1);
if(m == 1) return head;
ListNode cur = head;
for(int i = 2;i <= m;i++){
ListNode tmp = new ListNode(i);
cur.next = tmp;
cur = tmp;
}
cur.next = head;
return head;
}
}
另一种就是在构造循环链表过程中,直接将头指针定义为第k个猴子,后续操作和上篇代码一样。
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入猴子数N: ");
int n = sc.nextInt();
System.out.println("请输入开始报数编号K: ");
int k = sc.nextInt();
System.out.println("请输入出列数M: ");
int m = sc.nextInt();
if(k > n || m > n) {
System.out.println("编号K或者M不能大于猴子总数N");
System.exit(0);
}
ListNode head = createListNode(n, k);
int count = 1;
ListNode pre = null;
while(head.next != head){
pre = head;
head = head.next;
count++;
if(count == m){
System.out.println("当前出局人是: "+ head.val);
pre.next = head.next;
head = pre.next;
count = 1;
}
}
System.out.println("最后的大王是: "+ head.val);
}
public static ListNode createListNode(int n,int k){
ListNode head = new ListNode(k);
ListNode cur = head;
for(int i = k;i<n;i++){
ListNode tmp = new ListNode(i + 1);
cur.next = tmp;
cur = tmp;
}
for(int i = 0;i<k - 1;i++){
ListNode tmp = new ListNode(i + 1);
cur.next = tmp;
cur = tmp;
}
cur.next = head;
return head;
}