约瑟夫环问题

约瑟夫环问题(Josephus):
用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。

这是面试常用的算法题目,下面给出解法代码:

package com.zas.test;

import java.util.ArrayList;
import java.util.List;

/**
* 约瑟夫环问题
* @author zas
*/
public class Josephus {

/**
* n人队列 按照m报数获取最后一个人的编码
* @param n
* @param m
* @return
*/
public static int getLastNumber(int n, int m) throws IllegalArgumentException {
if(n < 1 || m < 1){
throw new IllegalArgumentException("参数有问题");
}
if(n == 1){
return 1;
}
List<Integer> list = new ArrayList<Integer>();
//初始化编码
for (int i = 1; i < n + 1; i++) {
list.add(i);
}

//队列剩余人数
int left = list.size();
//队列索引计数器 到队列大小时从新计数
int index = -1;
//报数计数器
int counter = 0;
//队列剩余大于1人时继续报数
while(left > 1){
//索引计数器加一
index = index + 1;
//报数计数器加一
counter = counter + 1;
//当报数到m时出列
if(counter == m){
System.out.println("出列 : " + list.remove(index));
if(left == index + 1){
index = -1;
}else{
index = index - 1;
}
counter = 0;
}else{
if(left == index + 1){
index = -1;
}
}
left = list.size();
}
return list.get(0);
}
/**
* @param args
*/
public static void main(String[] args) {
System.out.println(Josephus.getLastNumber(3,3));
}
}


该问题的要点在边界的处理:报数到要踢人的时候判断索引计数器与队列的剩余大小是否相等,并做索引、报数计数器重置操作;不需要踢人的时候,只做索引计数器重置。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值