Skip to content

经典案例 约瑟夫环

约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知 n 个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为 k 的人开始报数,数到 m 的那个人出圈;他的下一个人又从 1 开始报数,数到 m 的那个人又出圈;依此规律重复下去,直到剩余最后一个胜利者。

数组模拟

用数组求解的基本思想就是用一个一维数组去标识这 n 个人的状态,默认全为 1 ,也就是都在圈子内,当数到 m 的人出圈之后,标识置为 0(就是出圈了),同时报数器清 0,下一个人要从 1 开始。在每次报数之前要判断他是否在圈子内(也就是他的标识是否为 1 ),如果在圈子里面才会继续报数。定义一个变量记录出圈的人数, 出圈的人数等于 n-1 时,则游戏结束。

js
const joseph = (n ,m) => {
  let count = 0 ;  // 已经出圈了多少个
  let num = 0 ; // 报数器
  const list = new Array(n).fill(1)
  // 出圈人数达到 n - 1 退出循环
  while (count < n - 1) {
    // 遍历一遍数组,这里不要使用 forEach
    for (let i = 0; i < n; i++){
      if (list[i] === 0) continue;
      num += 1;
      if (num === m) {
        count += 1;
        list[i] = 0;
        num = 0;
      }
    }
  }
  // 找到 result
  let result = 0;
  for (let i = 0; i < n; i++){
    if (list[i] === 1){
      result = i;
      break;
    }
  }
  return result + 1;
}

console.log(joseph(10, 1))

链表模拟

递推公式