前端企业面试题:企业真实案例——28

请实现一个约瑟夫环

首先,你必须先搞清楚什么是约瑟夫环。

相传,在罗马人占领敲他帕特之后,39个犹太人跟约瑟夫以及他的朋友躲到了一个山洞中,39个犹太人决定宁死也不要被敌人抓到,于是决定了一个自杀方式,41个人围成一个圈,由第1个人开始报数,每报数到第3人,该人就必须自杀。然后再由下一个重新报数,直到所有人都自杀身亡为止。然而约瑟夫和他的朋友并不想遵从。他将朋友和自己安排在了第16个和第31个位置,于是逃过了这场死亡游戏。请问他是如何做到的?

它可以衍生为一个通用问题,假设有M个元素

前端企业面试题:企业真实案例——28_第1张图片

如果把每个人看做一个节点,他们形成了一个单向的循环链表

前端企业面试题:企业真实案例——28_第2张图片

 

我们现在假设K=3

前端企业面试题:企业真实案例——28_第3张图片

前端企业面试题:企业真实案例——28_第4张图片

 

当只剩下最后一个元素时

前端企业面试题:企业真实案例——28_第5张图片

于是我们的核心代码就可以写出来了

while(node.next != node){
    1 将指针移动K-1步
    2 重新建立连接删除当前节点
    3 修正指针位置到下一个
}

 

我们先准备节点类

function Node(name){
    this.name = name;
    this.next;
}

创建一个长度为10的单向循环链表

let head = temp = new Node(1);
for(let i=2; i<=10; i++){
    temp.next = new Node(i);
    temp = temp.next;
}
temp.next = head;

创建出我们的指针类

function Pointer(node){
    this.current = node;
    this.move = function(){
        this.prev = this.current; //记录前一格
        this.current = this.current.next; //当前节点向前移动一格
    }
}

 

接下来是完整代码

function Node(name){
    this.name = name;
    this.next;
}
function Pointer(node){
    this.current = node;
    this.move = function(){
        this.prev = this.current; //记录前一格
        this.current = this.current.next; //当前节点向前移动一格
    }
}
//准备好链表内容
let head = temp = new Node(1);
for(let i=2; i<=10; i++){
    temp.next = new Node(i);
    temp = temp.next;
}
temp.next = head;
//创建指针,从head开始
var p = new Pointer(head);
//设定间隔为3
let step = 3;
//只要next没有指向元素自身,则循环继续
while(p.current != p.current.next){
    //指针移动step-1步
    for(let i=0; i

你可能感兴趣的:(前端企业面试题:企业真实案例——28)