一、前言

约瑟夫问题可以说是非常经典的一道题了,面试官经常问,我有一次就遇上了它,不对,应该是它遇上了我!下面我就用一行代码来解决这道约瑟夫问题,这种方法你学会了之后就可以在面试官面前装B了。

二、解题

问题描述:编号为 1-N 的 N 个士兵围坐在一起形成一个圆圈,从编号为 1 的士兵开始依次报数(1,2,3...这样依次报),数到 m 的 士兵会被杀死出列,之后的士兵再从 1 开始报数。直到最后剩下一士兵,求这个士兵的编号。

其实我们可以用递归来解决这道题,递归是思路是每次我们删除了某一个士兵之后,我们就对这些士兵重新编号,然后我们的难点就是找出删除前和删除后士兵编号的映射关系。

我们定义递归函数 f(n,m) 的返回结果是存活士兵的编号,显然当 n = 1 时,f(n, m) = 1。假如我们能够找出 f(n,m) 和 f(n-1,m) 之间的关系的话,我们就可以用递归的方式来解决了。我们假设人员数为 n, 报数到 m 的人就自杀。则刚开始的编号为:


1
...
m - 2

m - 1

m

m + 1

m + 2
...
n

进行了一次删除之后,删除了编号为 m 的节点。删除之后,就只剩下 n - 1 个节点了,删除前和删除之后的编号转换关系为:

删除前 --- 删除后

… --- …

m - 2 --- n - 2

m - 1 --- n - 1

m ---- 无(因为编号被删除了)

m + 1 --- 1(因为下次就从这里报数了)

m + 2 ---- 2

… ---- …

新的环中只有 n - 1 个节点。且删除前编号为 m + 1, m + 2, m + 3 的节点成了删除后编号为 1, 2, 3 的节点。

假设 old 为删除之前的节点编号, new 为删除了一个节点之后的编号,则 old 与 new 之间的关系为 old = (new + m - 1) % n + 1。

注:有些人可能会疑惑为什么不是 old = (new + m ) % n 呢?主要是因为编号是从 1 开始的,而不是从 0 开始的。如果 new + m == n的话,会导致最后的计算结果为 old = 0。所以 old = (new + m - 1) % n + 1.
这样,我们就得出 f(n, m) 与 f(n - 1, m)之间的关系了,而 f(1, m) = 1.所以我们可以采用递归的方式来做。代码如下:

int f(int n, int m){if(n == 1)   return n;return (f(n - 1, m) + m - 1) % n + 1;
}

我去,两行代码搞定,而且时间复杂度是 O(n),空间复杂度是O(n),牛逼!那如果你想跟别人说,我想一行代码解决约瑟夫问题呢?答是没问题的,如下:

int f(int n, int m){return n == 1 ? n : (f(n - 1, m) + m - 1) % n + 1;
}

我cao,以后面试官让你手写约瑟夫问题,你就扔这一行代码给它。

三、总结

不过那次笔试时,并没有用递归的方法做,而是用链表的方式做,,,,,那时,不知道原来还能用一行代码搞定的,,,,欢迎各位大佬提供半行代码搞定的方法!

一行代码解决约瑟夫问题(我要开始装B了)相关推荐

  1. 【图解经典算法题】如何用一行代码解决约瑟夫环问题

    约瑟夫环问题算是很经典的题了,估计大家都听说过,然后我就在一次笔试中遇到了,下面我就用 3 种方法来详细讲解一下这道题,最后一种方法学了之后保证让你可以让你装逼. 问题描述:编号为 1-N 的 N 个 ...

  2. 消除左递归c++代码_【每日算法Day 85】图解算法:一行代码解决约瑟夫环的变体...

    题目链接 LeetCode 390. 消除游戏[1] 题目描述 给定一个从 到 排序的整数列表. 首先,从左到右,从第一个数字开始,每隔一个数字进行删除,直到列表的末尾. 第二步,在剩下的数字中,从右 ...

  3. [zz]一行代码解决iframe挂马(服务器端注入、客户端ARP注入等)

    一行代码解决iframe挂马(服务器端注入.客户端ARP注入等) 一行代码解决iframe挂马(包含服务器端注入.客户端ARP注入等) 本文原创:linr@cncert.net 请转载时保留版权信息 ...

  4. 一行代码解决ie浏览器的兼容

    x-ua-compatible 头标签大小写不敏感,必须用在 head 中,必须在除 title 外的其他 meta 之前使用. 1.使用一行代码来指定浏览器使用特定的文档模式. <meta h ...

  5. 有一个List集合,里面存储了5个Student对象。Student有姓名、年龄和成绩属性,按照多个属性进行排序(一行代码解决list对象集合排序问题)。

    有一个List集合,里面存储了5个Student对象.Student有姓名.年龄和成绩属性,按照要求进行排序(一行代码解决list对象集合排序问题). 要求对List集合进行排序,排序规则是: 1.先 ...

  6. python匿名基数(lamdba):给你一个整数数组nums,如果任一值在数组中出现至少两次,返回True;如果数组中每个元素互不相同,返回False,用一行代码解决

    """ 给你一个整数数组nums,如果任一值在数组中出现至少两次,返回True:如果数组中每个元素互不相同,返回False,用一行代码解决 例: nums = [1,2, ...

  7. 一个整合OkHttp 、Retrofit 、Volley 、RxJava、Novate多种开源网络框架的项目,高度的封装和集成,Android中Web网络请求一行代码解决

    一个整合OkHttp .Retrofit .Volley .RxJava.Novate多种开源网络框架的项目,高度的封装和集成,Android中Web网络请求一行代码解决 AndroidHttp 一个 ...

  8. 一行代码解决各种IE兼容问题

    一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10 前端面试秘籍,欢迎star! 在网站开发中不免因为各种兼容问题苦恼,针对兼容问题,其实IE给出了解决方案Google也给出了解决 ...

  9. 一行代码解决网页灰色

    一行代码解决网页灰色 // 实战中只搞首页就OK了 body{filter: grayscale(1); }

最新文章

  1. JS中IE与W3C不同的地方
  2. 算法打卡39:喷水装置
  3. 栈劫持(栈迁移)介绍
  4. Linux软件源apt,仓库,包的概念
  5. gpu填充速率 计算_【经典回顾】Nvidia GPU 上的 CNN 计算速度变迁
  6. .NET Core 3.1 的REST 和gRPC 性能测试
  7. setnx和expire合成一条指令_Python 为什么只需一条语句“a,b=b,a”,就能直接交换两个变量?...
  8. GYM101933I - Intergalactic Bidding
  9. jQuery常用的层次选择器
  10. Transform机制(1)
  11. 新萝卜家园windows11 64位官网正版系统v2021.07
  12. 使用python统计出txt文档中含有某个单词的个数
  13. VmBox硬盘容量调整
  14. PHP+Mysql+jQuery实现发布微博程序(PHP篇)
  15. java 命令参数详解
  16. PDF文件怎么才能编辑里面的内容
  17. 蓝桥杯训练系统 分解质因数
  18. 用python来更改小伙伴的windows开机密码,不给10块不给开机
  19. 135编辑器使用教程
  20. mysql spatial 函数_MySQL中spatial基本操作

热门文章

  1. python制作个性签名(最后有彩蛋)
  2. excel表格如何转变成PDF文件
  3. DNS轮询怎么实现?
  4. NO.009-2018.02.14《临江仙·送钱穆父》宋代:苏轼
  5. Linux下kiftd开机启动,解决Windows下kiftd无法正常启动的问题
  6. 服务器2008下快速删除文件,修改注册表 让Win2008操作更易上手
  7. python软件许可License文件生成
  8. eq值 推荐算法_EQ均衡器的算法,你知道多少?
  9. 天龙八部荣耀版 天龙h5 脚本辅助 定制开发
  10. 怎么查找计算机的内存卡,怎么查看电脑内存卡型号