就在我为之苦恼的时候,一位同事在我身旁经过,突然说了一句:“咦,这不是约塞夫问题吗?”
一、面试题
原题目不太明朗(一号到底杀不杀?)
于是把题目优化一下,更接近于原本的约塞夫问题
假设有100人,分别编号 1~100
从 1 号开始报数,报数到 3 号时,3 号就被淘汰,然后由下一人从 1 报数,以此类推
最后谁会活下来?
二、面向过程
最开始我按照自己的思路,模拟了整个过程
虽然能解决问题,但一旦遇到较大的数据量,查询的次数太多,性能太低
不过这种方法最容易理解
/** * 面向过程的约塞夫环解决办法 * @param {Array} peoples 参与游戏的数组 * @param {Number} kill 淘汰的报数数字 * @return {Object} 幸存者 */ function killer(peoples, kill) { let flag = 0 // 初始化报数 while(peoples.length > 1) { // 只剩下一个人时,循环结束 let len = peoples.length // 剩余人数 let out = 0 // 已淘汰的人数 for (let i = 0; i < len; i++) { flag++ // 报数+1 if (kill == flag) { // 当报数到指定数字,淘汰该玩家 // 淘汰后剩余人数(数组)会发生变化,所以被淘汰玩家下标应为 i-out peoples.splice(i-out, 1) flag = 0 // 重置报数 out++ // 淘汰人数+1 } } } return peoples[0] }