前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >约瑟夫环问题解决方法时间复杂度分析

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

作者头像
执生
发布2020-09-27 10:50:15
1.2K0
发布2020-09-27 10:50:15
举报
文章被收录于专栏:立权的博客立权的博客

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

  在牛客上跑通过了,本着追求机器效率的原则,去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),真的是数学可以造成降维打击......

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-07-22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档