您的位置:首页 > 编程语言 > Java开发

约瑟夫问题 之Java两种解决方案

2016-11-04 21:03 344 查看
前两天到京东面试,笔试题中有关于“约瑟夫”编程的题目,当时就懵了,那么短时间内也写不出来,最后没有写出来,是面试中的一大遗憾......
类似于这种的算法设计的题目变种很多,以下给出Java程序两种方案:


第一种方案:循环链表,具体代码如下,

package com.sniper;
public class Node {
private int no ;
private Node beforeNode;
private Node nextNode;

public Node(int no) {
this.no = no ;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public Node getBeforeNode() {
return beforeNode;
}
public void setBeforeNode(Node beforeNode) {
this.beforeNode = beforeNode;
}
public Node getNextNode() {
return nextNode;
}
public void setNextNode(Node nextNode) {
this.nextNode = nextNode;
}
}

//测试类
package com.sniper;

public class TestMain {
private static int TOTAL = 10;//总共多少人
private static int M = 3;//报数报到几,退出
public static void main(String[] args) {
Node node = init(TOTAL);
printNode(node);
play(node, TOTAL, M);

}

/**
* @TODO 初始化双向链表
* @return
*/
private static Node init(int total){
Node firstNode = null;
Node currentNode = null;
Node beforeNode = null;
for (int i = 1; i <= total; i++) {
Node node = new Node(i);
currentNode = node;
if (i == 1) {//处理头节点
firstNode = node;
currentNode = node;
beforeNode = node;

firstNode.setBeforeNode(firstNode);
firstNode.setNextNode(firstNode);
}else if (i == total) {//处理尾节点
beforeNode.setNextNode(currentNode);
currentNode.setBeforeNode(beforeNode);
currentNode.setNextNode(firstNode);

firstNode.setBeforeNode(currentNode);
}else {
beforeNode.setNextNode(currentNode);
currentNode.setBeforeNode(beforeNode);
beforeNode = currentNode;
}
}

return firstNode;
}

/**
* @TODO 打印循环列表
* @param node
*/
private static void printNode(Node node){
System.out.println("初始化链表开始======");
Node firstNode = node;
do{
System.out.print(node.getNo()+" ");
node = node.getNextNode();
}while (node != firstNode);
System.out.println();
System.out.println("初始化链表结束======");
}

/**
* @param total
* @param m
*/
private static void play(Node node,int total,int m){
for (int i = 1; i <=m; i++) {
if (node.getBeforeNode() == node) {
System.out.println();
System.out.println("最后退出的为:"+node.getNo());
break;
}
if (i == m) {//退出
//退出
node.getBeforeNode().setNextNode(node.getNextNode());
node.getNextNode().setBeforeNode(node.getBeforeNode());
System.out.print(node.getNo()+" ");
//当前节点设置
node = node.getNextNode();
//i恢复
i=0;
}else{
node = node.getNextNode();
}

}
}
}


第二种方案:数组方式,具体代码如下,

package com.sniper;

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

public class Test {

public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入总人数:");
int totalNum = scanner.nextInt();
System.out.print("请输入报数的大小:");
int cycleNum = scanner.nextInt();
yuesefu(totalNum, cycleNum);
}

public static void yuesefu(int totalNum, int countNum) {
// 初始化人数
List<Integer> start = new ArrayList<Integer>();
for (int i = 1; i <= totalNum; i++) {
start.add(i);
}
//从第K个开始计数
int k = 0;
while (start.size() >0) {
k = k + countNum;
//第m人的索引位置
k = k % (start.size()) - 1;
// 判断是否到队尾
if (k < 0) {
System.out.println(start.get(start.size()-1));
start.remove(start.size() - 1);
k = 0;
} else {
System.out.println(start.get(k));
start.remove(k);
}
}
}
}


完毕!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 约瑟夫