前言
数据结构与算法是程序员的内功,有时间还是要练习
一、何为约瑟夫问题
约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3,1。
现在问你最后留下的人是谁?
比如N=6,M=5
留下的就是1
1 2 3 4 5 6 => 6 1 2 3 4 => 6 1 2 3 =>1 2 3 => 1 3 => 1
二、代码实现
public class CircleLink {
private Node head;
private Node tail;
public CircleLink() {
this.head = null;
this.tail=null;
}
//构建循环链表,头插法
public void insertHead(int data){
Node newNode= new Node(data);
if(head==null){
head=newNode;
tail=head;
}else{
newNode.next=head;
head=newNode;
tail.next=head;
}
}
//删除某个值
public Node delNode(int data){
//从头部开始遍历
if(head.value==data){
tail.next=head.next;
head.next=null;
head=tail.next;
return head;//返回它的下一个值
}
Node point1=head;
Node point2=head.next;
while (point2.value!=data){
point1=point1.next;
point2=point2.next;
}
if(point2==tail){
tail=point1;
}
point1.next=point2.next;
point2.next=null;
return point1.next;//返回它的下一个值
}
public Node delByYusefu(int nums,Node node){
if(head==tail){
return head;
}
for (int i = 1; i <=nums-1 ; i++) {
node=node.next;
}
//System.out.println(node.value);
return delByYusefu(nums,delNode(node.value));
}
public static int lastValue(int n,int m){
CircleLink cl=new CircleLink();
for (int i = n; i >=1 ; i--) {
cl.insertHead(i);
}
Node node=cl.delNode(m);
return cl.delByYusefu(m, node).value;
}
public static void main(String[] args) {
int val=lastValue(6,6);
System.out.println("最后留下的值:"+val);
}
}
class Node{
public int value;
public Node next;
public Node(int value) {
this.value = value;
this.next=null;
}
}
运行如下:比如删除5
总结
感觉这次写的有些麻烦,有时间优化下