【Android面试】使用Java,有n个人(编号1~n围成一圈),从编号为1的开始报数,从1报数到m,报到m的人出去,下一个人继续从1开始报数,通过算法求最后一个留下的人的编号为多少

比如n=3,m=4

有3个人,从1报到4

第一次出队:1号

第二次出队:3号

最后留下:2号

使用链表来做最方便。

import java.util.Scanner;

public class LastOneStanding {
    
    
    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入人数n和报数范围m:");
        int n = sc.nextInt();
        int m = sc.nextInt();
        int[] nums = new int[n]; // 存储每个人的编号
        for (int i = 0; i < n; i++) {
    
    
            nums[i] = i + 1;
        }
        int lastIdx = 0; // 最后一个留下的人的编号初始化为0
        while (nums.length > 1) {
    
     // 当链表长度大于1时,继续循环
            int startIdx = 0; // 从哪个位置开始报数
            if (lastIdx == nums.length - 1) {
    
     // 如果上一个人是最后一个离开的人,从头开始报数
                startIdx = 0;
            } else {
    
     // 否则从上一个人的下一个位置开始报数
                startIdx = lastIdx + 1;
            }
            for (int i = startIdx; i < nums.length; i++) {
    
     // 从指定位置开始报数
                if (i == m) {
    
     // 如果报到m的人出去了,更新链表头指针和剩余人数
                    int nextIdx = nums[i % nums.length];
                    nums[0] = nextIdx;
                    lastIdx = 0;
                    if (nums.length == 1) {
    
     // 如果链表长度为1,说明只剩下一个人了,输出他的编号
                        System.out.println(nums[0]);
                        break;
                    }
                    nums[1] = nums[nums.length - 1]; // 将尾节点接在头节点后面,形成一个单节点的循环链表
                    nums[nums.length - 1] = 0; // 将尾节点置为0,表示已经删除掉该节点
                    nums[0] = i + 1; // 将新节点的编号设为i+1,表示该节点是新的头节点
                } else {
    
     // 如果没有报到m的人,将当前节点的编号加入到剩余人数中,并更新链表头指针和剩余人数
                    lastIdx++;
                }
            }
        }
        System.out.println("最后留下的人的编号为:" + nums[0]);
    }
}

猜你喜欢

转载自blog.csdn.net/qFAFAF/article/details/130743357
今日推荐