猴子选大王

题目描述:

N个猴子围成一个圈

1、从第一只猴子开始报数,第一只猴子报1

2、每个报2的猴子退出,然后从下一只猴子重新开始报数,

 3、要求输出退出的顺序和最后剩下的人

解题思路:

解法一:用数组解决,用数组存放1,2,3....N来表示N个猴子,然后不停的遍历数组,对于被选中的编号,我们可以将其标记为0,来表示该猴子已出局,然后按这种方法一直遍历数组,直到数组只有一个非0元素时,就表示已经找出最后一个猴子。

解法二:利用环形链表解决,这也是大多数人看到这个题第一个想出的方法,毕竟操作简单,易实现。它的具体思路就是用一个环形链表存放1,2,3....N来表示N个猴子。在利用一个count字段,初始值为1,统计count次数,当count = 2 时,就删除该节点(链表的删除结点在此不在展开),在使count置1,  循环的结束条件就是head.next = head即剩的最后一个元素。

public class ChooseKing {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入猴子数: ");
        int m = sc.nextInt();
        System.out.println("请输入出去间隔");
        int n = sc.nextInt();
        int count = 1;
        ListNode head = createListNode(m);
        ListNode pre = null;
        while(head.next != head){
            pre = head;
            head = head.next;
            count++;
            if(count == n){
                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;
    }

}

class ListNode{
    public int val;

    public ListNode next;

    public ListNode(int val){
        this.val = val;
    }
}

解法三:是用递归来解决的,此方法只能输出最后出局的猴子编号,所以下面会直接附上代码。

 /**
     *
     * @param n  猴子个数
     * @param m  第m个猴子出去
     * @return
     */
    public static int chooseKing(int n,int m){
        return n == 1? n:(chooseKing(n-1,m) + m -1) % n + 1;
    }

 

posted @ 2022-02-24 23:55  码到成功hy  阅读(148)  评论(0编辑  收藏  举报
获取

hahah

name age option