【算法学习】约瑟夫环(含公式思想总结)(Java)

2023-05-16

目录

    • 一、题目描述
    • 二、思路分析
        • 思路1:模拟
        • 思路2:数学方法
          • 递推公式:
          • 推导思路
            • why 为什么可以倒推
            • how 如何倒推
    • 三、参考代码
    • 四、测试连接

一、题目描述

这个问题是以弗拉维奥·约瑟夫命名的,他是1世纪的一名犹太历史学家。他在自己的日记中写道,他和他的40个战友被罗马军队包围在洞中。他们讨论是自杀还是被俘,最终决定自杀,并以抽签的方式决定谁杀掉谁。约瑟夫斯和另外一个人是最后两个留下的人。约瑟夫斯说服了那个人,他们将向罗马军队投降,不再自杀。约瑟夫斯把他的存活归因于运气或天意,他不知道是哪一个。 ——【约瑟夫问题】维基百科

0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。

例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。

示例 1:
输入: n = 5, m = 3
输出: 3

示例 2:
输入: n = 10, m = 17
输出: 2

二、思路分析

思路1:模拟

通过循环链表,循环模拟数字剔除,进过测试,执行超时。

思路2:数学方法

不得不说,通过数学推导归纳得出公式后写代码,不仅简洁,执行效率也很高

递推公式:

f ( n , m ) = { 0 , n = 0 ( f ( n − 1 , m ) + m ) % n n > 0 f(n,m) = \begin{cases} 0, & \text{n = 0} \\ (f(n-1, m) + m)\%n & \text{n > 0} \\ \end{cases} f(n,m)={0,(f(n1,m)+m)%nn = 0n > 0

看了很多leetcode上的题解,以及约瑟夫环公式的原理推导,讲的都比较抽象,自己总结如下推导。

推导思路

以初始化有 n 个数,没 m 个剔除,使用 L(n) 代表长度为 n 的序列,设解为 F(n, m) 使用大 F 仅仅因为小 f 不太好看,并没有别的意图

  1. 首先将问题定位为递归分治问题(一方面是看题解得出,另一方面据说“万物皆可分治”)
  2. 既然是递归问题,就可以提出假设,假设 F(n-1) 已经算好了。
  3. 基于思路2问题已经十分简单了,只需要根据 F(n-1, m) 推导出 F(n, m) 即可

针对思路3 力扣 题解中给出很多种倒推,看了好几篇不知其所以然。实际上就是为什么可以倒推如何倒推的问题,题解中大多只给出如何倒推。

why 为什么可以倒推

可以倒推的原因是因为 L(n-1) 的序列是从 L(n) 序列里剔除一个数,并调整顺序得来,具体如下图所示:
在这里插入图片描述
L(n) 实际上等价于 L(n - 1) 在最后补个 2(或者说,在L(n - 1)后补个 2, 与 L(n) 计算得出结果存在关系),因此,可以通过 L(n - 1) 序列的结果反推,L(n) 的结果。

为什么能等价呢? 约瑟夫环,【环】,列顺序一样结果就一样,上图中 L(n - 1) 对应的环,就等价于 L(n) 删除 2 后第二轮报数 (反之,L(n-1) 补全 2 再回退一次报数,就等价于 L(n) 初始状态) 如下图所示:
在这里插入图片描述

how 如何倒推

明白了为什么可以倒推,如何倒推就很简单了,首先对上图中 L(n-1) 进行简化,如下图所示:
在这里插入图片描述
L’(n-1) 是从 0 开始新序列,L’(n-1) 的结果通过 思路2 中假设 F(n-1, m) 已经被计算出来了是 X’,即 F(n-1, m) = X’。那么,转换到 L(n-1) 中可通过 X = (X’ + m) % n 得出。首先 +m 是从 0 开始和从 3 开始的对齐, %n 是因为 m 可能大于 n。

至此,就可以推算出上文提到的公式

三、参考代码

class Solution {
    public int lastRemaining(int n, int m) {
        if(n == 1) return 0;
        
        int x = lastRemaining(n-1, m);
        return (x + m) % n;
    }
}

四、测试连接

力扣

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【算法学习】约瑟夫环(含公式思想总结)(Java) 的相关文章

  • Anaconda常用命令大全

    使用conda 首先我们将要确认你已经安装好了conda 配置环境 下一步我们将通过创建几个环境来展示conda的环境管理功能 使你更加轻松的了解关于环境的一切 我们将学习如何确认你在哪个环境中 xff0c 以及如何做复制一个环境作为备份
  • openCV错误模块‘cv2.face‘没有属性‘createEigenFaceRecognizer‘(openCV Error module 'cv2.face' has no at

    pip uninstall opencv contrib python pip install opencv contrib python no cache dir 功能也更改为此 load被替换为read import cv2 recog
  • Python enumerate() 函数

    enumerate 函数用于将一个可遍历的数据对象 如列表 元组或字符串 组合为一个索引序列 xff0c 同时列出数据和数据下标 xff0c 一般用在 for 循环当中 Python 2 3 以上版本可用 xff0c 2 6 添加 star
  • python3 opencv3 实现基本的人脸检测、识别功能

    encoding utf 8 老杨的猫 环境 PYCHARM xff0c python3 6 opencv3 import cv2 os import cv2 face as fc 此处有坑 找不到脸 这样引用程序可以运行 xff0c 欢迎
  • idea修改maven镜像

    https jingyan baidu com article c33e3f482455d2ea15cbb526 html https blog csdn net qq 32588349 article details 51461182 阿
  • Error:(1, 1) java: 非法字符: ‘\ufeff‘

    一 问题 用IDEA打开eclipse java项目编译时 xff0c 出现以下错误 xff1a Error 1 1 java 非法字符 ufeff Error 1 10 java 需要class interface或enum 二 原因分析
  • Zemax学习笔记(4)- 设计单透镜实例_1,设置

    Zemax学习笔记 xff08 4 xff09 设计单透镜 1 xff0c 设置 简介镜头分类参数和设计约束镜头数据编辑器定义系统设置定义视场设置波长插入表面输入镜头数据求解 设计单透镜分为3个部分 xff0c 设置 分析和优化 xff0c
  • libnet安装配置

    安装编译 1 下载安装包 http sourceforge net projects libnet dev 2 解压 tar zxvf libnet 1 2 rc3 tar gz 3 进去编译 configure make make ins
  • idea 创建Spring第一个项目

    1 知道什么是maven 网上一般说maven是一个构建工具 xff0c 其实是说得很准确的 xff0c 不过我觉得更准确的说法应该是一个自动化的构建工具 你可以这样说 xff1a 不用maven的时候所有的jar都不是你家的 xff0c
  • anconda 安装dlib

    pip install CMake pip install Boost 前面两个不知道有没有用 xff0c 我是直接安装了 pip install dlib 会直接报错 xff0c 所以要到网上下载whl文件来安装 xff0c 就可以了 用
  • nodejs学习五:sequelize数据库查询的Op方法

    span class token comment 查找users表数据name span span class token keyword const span op span class token operator span model
  • 使用diskpart修复EFI分区变主分区的问题

    diskgenius有时操作EFI分区会把EFI变成主分区 xff0c 太弱智了 xff0c 呵呵 xff0c 但是这个EFI分区本身有可能会变成主分区 xff0c 这样的话系统就无法识别了 xff0c Win8 1系统的diskpart可
  • 程序员会设计后是一种什么样的感觉

    我是一个iOS开发的程序员 xff0c 也是一个自由职业者 平时靠接一些外包和做自己的产品为生 做了这么多年 xff0c 给我的感觉是 xff1a 如果你只会写程序 xff0c 那么做自由职业者的空间要小很多 01 我为什么要学设计 做自己
  • win10笔记本使用virtualbox鼠标失灵

    win10笔记本使用virtualbox6时 xff0c 发现鼠标移动偏差极大 xff0c 完全无法操作虚拟机 解决方法 xff1a 虚拟机设置中将指点设备切换为USB触控板 xff0c 运行虚拟机后右下角鼠标处右键 xff0c 勾选鼠标集
  • SpringMVC的常用注解

    SpringMVC的常用注解 1 64 Controller 64 Controller 用于标记在一个类上 xff0c 使用它标记的类就是一个SpringMVC Controller 对象 2 64 RequestMapping 用于处理
  • Hive学习之修改表、分区、列

    修改表的语句允许改变现有表的结构 通过该语句可以增加列 分区 修改SerDe 增加表和SerDe的属性或者重命名表 与之类似 修改分区的语句可以改变指定分区的属性 重命名表 重命名表的语句如下 ALTER TABLE table name
  • sftp通过秘钥上传,修改文件

    sftp是通过openssh与服务端建立连接的 xff0c 默认端口为22 1 新建一个sftp的用户 xff0c 这里就叫sftp useradd span class hljs operator s span sbin nologin
  • 说说win32 控制台应用程序、win32 项目、mfc项目、空项目那些事儿

    首先 xff0c 说一下空项目 xff0c 大多数想单纯创建c 43 43 工程的新同学 xff0c 打开vs后很可能不知道选择创建什么工程 xff0c 这时候请相信我 xff0c 空项目是你最好的选择 因为空工程不包含任何的源代码文件 x
  • Docker常用命令,使用脚本在线或者离线安装Docker

    查看 停止 删除container 查看运行的容器 docker ps 查看所有容器 docker ps a 查看所有容器id docker ps aq 先停止运行container xff0c 再删除container xff0c 再删除
  • Spring配置数据源(XML)

    1 数据源 xff08 连接池 xff09 的作用 数据源 连接池 是提高程序性能如出现的 事先实例化数据源 xff0c 初始化部分连接资源 使用连接资源时从数据源中获取 使用完毕后将连接资源归还给数据源 常见的数据源 连接池 xff1a

随机推荐

  • Python开发GUI工具介绍,实战:将图片转化为素描画!

    阳光普照好刺眼 7月华为云社区与csdn联合举办了黑马程序员的征文活动 xff0c 由于规则简单 xff08 保证原创文章 内容为技术类为主 且文章篇幅1000字 43 即可 xff09 xff0c 所以兴高采烈的参加了活动 本来是抱着打酱
  • spring boot配置加载不出来?

    新建一个项目发现不能用 xff0c maven依赖加载不出来 xff0c 问题界面如下 xff1a 可以明确是maven依赖出了问题 xff0c 检查配置 1 xff09 检查本地仓库是否配置正确 xff1a span class toke
  • iOS NSAttributedString(属性字符串)

    NSAttributedString实际上就是一个字符串和一本字典 字典包含每一个字符的属性 xff1a 包括字体 大小 下划线 颜色等等 关键是要知道字典中每个key的含义以及相应value的取值范围 Character Attribut
  • 无人机姿态解算_互补滤波(1)

    一 基础知识 1 坐标系 xff1a 遵循右手定则 1 1 大地坐标系 xff08 地球坐标系 xff09 xff1a 北 xff08 x轴 xff09 东 xff08 y轴 xff09 地 xff08 z轴 xff09 xff0c 地就是
  • 学会 Go 中的时间处理

    作为程序员 xff0c 我们经常需要对时间进行处理 在 Go 中 xff0c 标准库 time 提供了对应的能力 本文将介绍 time 库中一些重要的函数和方法 xff0c 希望能帮助到那些一遇到 Go 时间处理问题就需要百度的童鞋 应对时
  • Ubuntu修改文件权限

    Linux内的一切皆文件 xff0c 所以对于Linux下文件的管理就十分的重要了 Linux下的文件权限分为三种 xff1a r xff08 读 xff09 xff0c w xff08 写 xff09 xff0c x xff08 执行 x
  • Libnet简单学习

    简单了解后 xff0c 建议直接查看源码 xff0c 以获得其他函数 xff1a libnet libnet functions h File Reference 本文仅列举个别常用函数 libnet工作流程 xff08 1 xff09 通
  • Java模拟生产者消费者模型【仅代码 + 注释】

    模拟仓库容量为1 xff0c 1个消费者 xff0c 1个生产者的生产者消费者模型 span class token keyword package span span class token namespace com span clas
  • PHP8.2 Apache24 Windows10安装步骤

    PHP8 2 Apache24 Windows10安装步骤 1 官网地址 https httpd apache org download cgi 修改1 xff1a Define SRVROOT D WorkSoft Apache Apac
  • navicat乱码和激活

    乱码 xff1a 1 将export LANG 61 34 zh CN UTF 8 34 2 工具 gt 选项下常规 编辑器 xff0c 记录下的字体选Noto sans CJK相近字体 激活 xff1a 第一次执行start navica
  • OnclickListener

    相信很多像我一样的新手学习ANDROID开发会遇到这个问题 xff0c 通过这几天的归类和总结 xff0c 将我的理解写在下面 xff0c 欢迎大家一起前来讨论 xff1a 以按钮BUTTON的监听事件为例 xff0c 以下的监听实现都是等
  • 关于Activity的onNewIntent方法

    前言 onNewIntent方法想必大家都知道 xff0c 是和Activity的启动模式结合起来使用的 xff0c 可以这个方法具体什么情况下被调用 xff0c 如何使用你清楚了吗 xff1f 今天就来一探究竟 xff0c 扫清疑惑 实验
  • 【算法学习】二分查找 binary-search (Java 参考)

    题目描述 给定一个 n 个元素有序的 xff08 升序 xff09 整型数组 nums 和一个目标值 target xff0c 写一个函数搜索 nums 中的 target xff0c 如果目标值存在返回下标 xff0c 否则返回 1 思路
  • 【算法学习】二维数组检索 search-a-2d-matrix(Java)

    题目描述 请写出一个高效的在m n矩阵中判断目标值是否存在的算法 xff0c 矩阵具有如下特征 xff1a 每一行的数字都从左到右排序 每一行的第一个数字都比上一行最后一个数字大 例如 xff1a 对于下面的矩阵 xff1a 1 3 5 7
  • 【算法学习】二维数组查找(Java)

    一 题目描述 此题源于 剑指 offer 在一个二维数组中 xff08 每个一维数组的长度相同 xff09 xff0c 每一行都按照从左到右递增的顺序排序 xff0c 每一列都按照从上到下递增的顺序排序 请完成一个函数 xff0c 输入这样
  • 【算法学习】链表数相加(Java)

    一 题目表述 给定两个代表非负数的链表 xff0c 数字在链表中是反向存储的 xff08 链表头结点处的数字是个位数 xff0c 第二个结点上的数字是十位数 xff09 xff0c 求这个两个数的和 xff0c 结果也用链表表示 输入 xf
  • 【算法学习】最长公共子序列(Java)

    一 题目描述 给定两个字符串 text1 和 text2 xff0c 返回这两个字符串的最长公共子序列的长度 一个字符串的 子序列 是指这样一个新的字符串 xff1a 它是由原字符串在不改变字符的相对顺序的情况下删除某些字符 xff08 也
  • JFugue4.0 中文说明

    简介 由音符 八度 音长 音色 xff08 乐器 xff0c 默认乐器为钢琴 xff09 组成 和弦 连音 速冻 控制器 键签名 Jfugue 可以简单并且允许工程师去快速创建音乐的原因是 MusicString xff0c 一个特殊格式描
  • 【算法学习】有效括号 valid-parentheses (Java 参考)

    题目描述 给定一个只包括 xff0c xff0c xff0c xff0c xff0c 的字符串 xff0c 判断字符串是否有效 有效字符串需满足 xff1a 左括号必须用相同类型的右括号闭合 左括号必须以正确的顺序闭合 注意空字符串可被认为
  • 【算法学习】约瑟夫环(含公式思想总结)(Java)

    目录 一 题目描述二 思路分析思路1 xff1a 模拟思路2 xff1a 数学方法递推公式 xff1a 推导思路why 为什么可以倒推how 如何倒推 三 参考代码四 测试连接 一 题目描述 这个问题是以弗拉维奥 约瑟夫命名的 xff0c