约瑟夫环--链表解法

问题描述:N个人围成一圈,从第一个人开始报数,报到m的人出圈,剩下的人继续从1开始报数,报到m的人出圈;如此往复,直到所有人出圈。(模拟此过程,输出出圈的人的序号)

思路:借助循环链表思想,一维数组模拟即可,计算出每次需要移动到的位置,然后将这个数移除,指针后移继续,直到数组为空。移除的思路:在移动的过程中记录前一个位置,改变pre的指向,即跳过这个数指向下一个树

import java.util.Scanner;

public class ysfCircle {
	static Scanner in = new Scanner(System.in);
	public static void main(String[] args) {
        int n = in.nextInt();
        int m = in.nextInt();
        int cnt = n;
        int pre = n-1;
        int cur = 0;
        int[] circle = new int[n];
        for (int i = 0; i < circle.length; i++) {
			   circle[i] = (i+1)%n;//建立循环链表
//			   System.out.println(i+" "+circle[i]);
		}
        int[] ans = new int[n];
        int te = 0;
        while(cnt>0) {
        	int num = m%cnt-1;//要移动到的位置
        	for (int i = 0; i < (num==-1?cnt-1:num); i++) {
				pre = cur;//记录前一个位置
				cur = circle[cur];//移动到下一个
			}
             ans[te++] = cur+1;//记录结果值(索引值从0开始)
             cnt--;
             circle[pre] = circle[cur];//将这个数移除
             cur = circle[cur];// 从下一个数开始
        }
        for (int i : ans) {
			System.out.print(i+" ");
		}
        System.out.println();
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值