前端算法
首发于前端算法

约瑟夫环

有100个人,环成一圈开始报数,从1数起,数到7就枪毙一个,然后继续从1数起,数到7就枪毙一个,直到所有枪毙。求所有人的死亡顺序。

解一

使用哈希大法,不断将枪毙的人标记到哈希中

    function kill() {
      var ret = [], map = {}, j = 0, loopIndex = 0
      do {
        for (var i = 1; i <= 100; i++) {
          if (!map[i]) {
            j++
            if (j === 7) {
              ret.push(i)
              map[i] = true
              j = 0
            }
          }
          loopIndex++
        }
        if (ret.length === 100) {//所有人枪毙完
          break
        }
      } while (1);
      console.log(ret)
      console.log("测试复杂度", loopIndex)
      return ret;
    }
    kill()

好写好有,就是复杂度有点高,外循环跑了34次。但数组又不方便移除,虽然说JS有splice方法。


解二

弄一个链表,然后围起来枪毙,挂掉的踢出圈子。

  function kill2() {
      var ret = [], j = 0
      var head, node
      for (var i = 1; i <= 100; i++) {
        if (!node) {
          node = {
            value: i
          }
          head = node
        } else {
          node = node.next = {
            value: i
          }
        }
      }
      node.next = head;
      //形成一个环链表
      var loopIndex = 0
      var prev = node;
      var curr = head;
      while (curr.next) {
        var next = curr.next
        loopIndex++
        if (curr === next) {
          //只剩下自己了
          ret.push(curr.value)
          break
        }
        j++
        if (j === 7) {//喊号为7的倒霉蛋
          curr.next = null
          prev.next = next;
          ret.push(curr.value)
          curr = next
          j = 0
          continue
        }
        prev = curr
        curr = next
      }
      console.log(ret)
      console.log("loopIndex", loopIndex)
      return ret
    }
    kill2()

解三

在生成链表时,可以求解一部分答案,对应的数就不用变成节点,这样链表也短很多。

 function kill3() {
      var ret = [], j = 0
      var head, node, begin
      for (var i = 1; i <= 100; i++) {
        if (i % 7 == 0) { //减少链表的生成
          ret.push(i)
          begin = node;//链表的开始
          continue
        }
        if (!node) {
          node = {
            value: i
          }
          head = node
        } else {
          node = node.next = {
            value: i
          }
        }
      }
      node.next = head;
      //形成一个环链表
      var loopIndex = 0
      var prev = begin
      var curr = prev.next
      while (curr.next) {
        var next = curr.next
        loopIndex++;
        if (curr === next) {
          ret.push(curr.value)
          break
        }
        j++
        if (j === 7) {
          curr.next = null
          ret.push(curr.value)
          prev.next = next;
          curr = next
          j = 0
          continue
        }
        prev = curr
        curr = next
      }
      console.log(ret)
      console.log("loopIndex", loopIndex)
      return ret
    }
    kill3()

发布于 2019-07-05

文章被以下专栏收录