• 约瑟夫环问题解决方法时间复杂度分析


      写这篇博客的起因是在牛客上刷到了一道约瑟夫环相关的题。牛客链接

      在牛客上跑通过了,本着追求机器效率的原则,去leetcode上找到了同样的题,再跑了一遍,发现超时。看了几篇博客并思索许久后打算写这篇博客来探究

    约瑟夫环问题在选取不同数据结构和不同处理方法的时候时间复杂度的优劣。leetcode链接

      关于约瑟夫环及其递推公式请见:https://blog.csdn.net/u011500062/article/details/72855826

      需要解释的是为什么受害者之前位置的人在下一轮的下标是(当前下标 - m)% 当前一轮的人数

    分析时间复杂度:

      如果要去直接模拟约瑟夫问题的各个环节的话,因为每次都要报数报m次,不考虑具体是什么数据结构实现存储,n个人需要报 n - 1次数,那么问题规模是O(n * m)

      考虑具体使用的数据结构,比如数组,0号位代表一号人,1号位代表二号人,以此类推,那么有两种方法:

        1.每当有一个人遇害,就把这个人从数组中删去,并且将此人后面的人向前移动。

        2.只是把遇害者的位置标记,不删除该位置,之后访问的时候检查到某个位置的值之前标记过的话就跳过(没有人在这个位置上)

      第一种情况,总共要挪动多少人 具体是难以推测的,因为每次都是以m为位移在当前数组上找下一个位置,但是可以假设最坏情况,每次移动的人数是当前数组人数 - 1

    那么总的移动次数是 : (n - 1) + (n - 2) + (n - 3) + ...... + 1 = (n - 1) * n / 2 , 是 O(n ^ 2)级的。

      第二种情况,属于暴力遍历,如果路途中没有遇到之前的遇害者位置,那么访问次数是 m,但是每有一个人遇害,遇害者位置就会 + 1, 所以每次的遍历次数 > m,越遍历下去情况越糟糕,因为人死得越来越多,需要访问-跳过的槽位也越来越多。总次数  > n * m

      用Java实现:

      其实第一种情况,对应于使用ArrayList,因为他的底层实现就是数组,并且每次删除元素都会把后面的元素平移。

      第二种情况,没有什么类似的ADT实现,但是LinkedList有类似之处,LinkedList不能像ArrayList那样直接通过下标找到元素,而是需要一个节点一个节点地next来获取某个

    下标位置的元素

      至于公式推导法......因为是从 2 到 n 遍历,相当于线性时间复杂度 O (n),真的是数学可以造成降维打击......

  • 相关阅读:
    字符串的基本操作
    PHP & Delphi 語法
    Delphi项目构成之单元文件PAS
    Delphi项目构成之项目文件DPR
    Delphi项目的构成
    關於那我的編程歷史..
    點擊Button,在Label1顯示HelloWorld!。
    開博客了, 因為搞Delphi 開發的關於Delphi學習
    Java 基础知识(一)
    关于多线程对于全局变量的资源竞争问题
  • 原文地址:https://www.cnblogs.com/lqlqlq/p/13363654.html
Copyright © 2020-2023  润新知