我在Java语言的O'Reilly数据结构和算法中发现了这个问题:“根据传说,第一世纪的犹太历史学家弗拉维乌斯·约瑟夫斯(Flavius Josephus)关于 在战役中被罗马士兵和40名同胞俘虏 犹太罗马战争。犹太士兵决定,他们宁愿自杀而不愿自杀。 捕获并制定了消亡计划。他们要围成一圈杀死 每三名士兵都死了。约瑟夫斯和另一个人决定 不想这一切,并迅速计算出他们需要放置自己的位置 因此他们将是最后的幸存者。编写一个程序,让您放置 围成一个圈,并指定每个mth人将被杀死。该程序 应该确定圈子中剩下的最后两个人的人数。循环使用 链接列表来解决问题。”
这是我的解决方法
function Node(element) {
this.element = element;
this.next = null;
}
function LList() {
this.head = new Node("head");
this.head.next = this.head;
this.find = find;
this.insert = insert;
this.display = display;
this.findPrevious = findPrevious;
this.remove = remove;
this.advance = advance;
this.count = count;
}
function remove(item) {
var prevNode = this.findPrevious(item);
if (!(prevNode.next == this.head)) {
prevNode.next = prevNode.next.next;
}
}
function findPrevious(item) {
var currNode = this.head;
while (!(currNode.next == this.head) &&
(currNode.next.element != item)) {
currNode = currNode.next;
}
return currNode;
}
function display() {
var currNode = this.head;
while (!(currNode.next == this.head)) {
print(currNode.next.element);
currNode = currNode.next;
}
}
function count() {
var currNode = this.head;
var count = 0;
while (!(currNode.next == this.head)) {
count++
currNode = currNode.next;
}
return count;
}
function find(item) {
var currNode = this.head;
while (currNode.element != item) {
currNode = currNode.next;
}
return currNode;
}
function insert(newElement, item) {
var newNode = new Node(newElement);
var current = this.find(item);
newNode.next = current.next;
current.next = newNode;
}
function advance(item, n) {
var currNode = this.find(item);
for (let i = n; i > 0; i--) {
currNode = currNode.next;
}
return currNode;
}
function survivor(number, position) {
//40 compatriots
//kill every third soldier. advance by 3
//last two survivors
//place n people in a circle
var compatroits = new LList();
var currNode = compatroits.head;
for (let i = 1; i <= number; i++) {
compatroits.insert(i, currNode.element);
currNode = currNode.next;
}
//kill every mth person in the circle
//start from head
var currItem = compatroits.head.element;
while (compatroits.count() > 2) {
//advance mth person
var killNode = compatroits.advance(currItem, position);
//set new start point to m.next node
currItem = killNode.next.element;
//remove mth person
compatroits.remove(killNode.element);
}
//determine the last two people in the circle
return compatroits.display();
}
有人能更有效地解决问题吗?