【错题集-编程题】孩子们的游戏(圆圈中最后剩下的数)(约瑟夫环)

简介: 【错题集-编程题】孩子们的游戏(圆圈中最后剩下的数)(约瑟夫环)

题目链接:孩子们的游戏(圆圈中最后剩下的数)_牛客题霸_牛客网 (nowcoder.com)


一、分析题目

解法⼀:模拟。这⾥不多赘述,⽤数组或者链表模拟均可。数组:用一个 bool 数组来记录 i%n 的位置是否被喊到;链表:通过不断删除删除节点并更改指针指向来进行模拟。


解法⼆:迭代 / 递归 / 动态规划(数学规律)

(1)递归:

n 个数向后去掉第 m 个数,还剩下 n−1 个数,依然要继续去掉第 m 个数。由此,从 (n, m) 的问题变成了 (n−1, m) 的子问题,其中若是 (n−1, m) 的子问题返回的最后一个数是 x,则 (n, m) 返回的结果就是 (m+x)%n,因此用递归解决。

  • 终止条件:当 n=1 时就只剩下了最后一个孩子,应该返回 0。
  • 返回值:子问题的结果加上 m 再对 n 取模,就是上一级删除的元素。
  • 本级任务:递归进入子问题获取子问题删除的元素,再推算自己这一级删除的元素。

具体做法:

  • step 1:首先判断没有小朋友的特殊情况。
  • step 2:然后递归计算子问题,并将子问题的结果 x 运算 (m+x)%n 得到父问题的结果。

(2)迭代

也可以用迭代来代替递归,递归是自顶向下找子问题,根据子问题再自顶向上返回给父问题,来推算父问题的结果。我们可以直接从小的子问题,往上推,还是根据公式 (m+x)%n,只是这里的 n 变成了每一级子问题的长度。

for (int i = 2; i <= n; i++)
    x = (m + x) % i;

具体做法:

  • step 1:首先判断没有小朋友的特殊情况。
  • step 2:假设最后剩余 1 个的时候,结果肯定为 0。
  • step 3:从最后剩余 1 个小朋友推断 2 个,再不断根据公式推断到 n 个。

(3)动态规划:

  • 状态表示:dp[i] 表示:当有 i 个孩子围成一圈时,最终获胜的孩子的编号是多少。
  • 初始化:dp[1] = 0(这个很好理解:只有一个孩子,那么获胜编号就是 0)
  • 递推关系:dp[i] = (dp[i-1] + m) % i

通过画图,可以找到相邻两次删除坐标的规律。通过递推关系,求出剩下的最后⼀个数是哪个。


二、代码

1、解法一

//使用容器vector
class Solution {
public:
    int LastRemaining_Solution(int n, int m)
    {
        vector<int> circle;
        for(int i=0; i<n; i++)
            circle.push_back(i);
 
        int start = 0;
        while(n > 1)
        {
            start = (start + m - 1) % n;
            circle.erase(circle.begin() + start);
            n--;
        }
        return circle[0];
    }
};

2、解法二

//递归
class Solution {
public:
    int f(int n, int m) {
        if (n == 1)  
            return 0;
        int x = f(n - 1, m);
        return (m + x) % n;  
    }
    int LastRemaining_Solution(int n, int m) {
        return f(n, m);
    }
};
 
//迭代
class Solution {
public:
    int LastRemaining_Solution(int n, int m) {
        int x = 0;
        for(int i = 2; i <= n; i++)
            x = (m + x) % i;
        return x;
    }
};
 
//动态规划
class Solution
{
public:
    int LastRemaining_Solution(int n, int m) 
    {
        vector<int> dp(n+1);
        dp[0] = 1;
        for(int i = 1; i <= n; i++) dp[i] = (dp[i-1] + m) % i;
        return dp[n];
    }
};
 
//动态规划-优化:滚动数组
class Solution {
public:
    int LastRemaining_Solution(int n, int m) {
        int f = 0;
        for(int i = 2; i <= n; i++) f = (f + m) % i;
        return f;
    }
};

三、反思与改进

拿到这道题的时候,真是感觉陌生又熟悉,因为之前有接触过,不过已经把其中的数学规律给忘记了。第一想法是递归,但没什么思路,然后尝试用数组模拟,有很多细节没考虑到,结果只能通过一些样例,其实这时候应该把特殊情况考虑上,就可以多拿一点分。接着后面想过要不用链表来写,但不知道为什么这个想法很快就被自己否决了,估计是知道这题是找规律所以懒得用链表做吧,其实链表需要考虑的细节没有那么多,或许用链表写一遍,思路可以更加清晰,下次不要轻易否决一个 idea。看了一下题解,果然自己还是考虑的太少了,应该多模拟几个样例,寻找其中的规律。


相关文章
|
运维 Kubernetes Nacos
nacos常见问题之集成nacos时 端口9848报错如何解决
Nacos是阿里云开源的服务发现和配置管理平台,用于构建动态微服务应用架构;本汇总针对Nacos在实际应用中用户常遇到的问题进行了归纳和解答,旨在帮助开发者和运维人员高效解决使用Nacos时的各类疑难杂症。
|
2月前
|
存储 自然语言处理 安全
大模型应用:医疗行业大模型:从生成前校验到生成后审计的应用实践.73
本文提出医疗大模型“生成前校验+生成后审计”全链路管控方案,通过输入完整性/合规性校验、隐私脱敏、标准化处理,及输出格式/准确性/隐私审计等闭环流程,确保病历撰写、医嘱辅助等场景安全、合规、准确落地。
418 7
基于PID控制器的异步电机矢量控制系统simulink建模与仿真
本课题研究基于PID控制器的异步电机矢量控制系统,利用Simulink建立仿真模型,分析系统在不同工况下的运行性能。通过矢量控制技术实现对电机转速和转矩的高精度调节,验证了PID控制器在系统中的良好控制效果,提升了异步电机的稳定性和响应性,具有较强的工程应用价值。
|
SQL 关系型数据库 MySQL
Flink CDC 3.4 发布, 优化高频 DDL 处理,支持 Batch 模式,新增 Iceberg 支持
Apache Flink CDC 3.4.0 版本正式发布!经过4个月的开发,此版本强化了对高频表结构变更的支持,新增 batch 执行模式和 Apache Iceberg Sink 连接器,可将数据库数据全增量实时写入 Iceberg 数据湖。51位贡献者完成了259次代码提交,优化了 MySQL、MongoDB 等连接器,并修复多个缺陷。未来 3.5 版本将聚焦脏数据处理、数据限流等能力及 AI 生态对接。欢迎下载体验并提出反馈!
1926 1
Flink CDC 3.4 发布, 优化高频 DDL 处理,支持 Batch 模式,新增 Iceberg 支持
|
网络安全
Xshell7连接Debian12系统,中文显示乱码,解决办法一览!
在使用Xshell 7连接Debian 12时,中文乱码通常由字符编码或字体设置不当引起。解决方法包括:1) 设置Xshell编码为UTF-8;2) 配置支持中文字体(如Microsoft YaHei);3) 调整Debian 12的Locale配置,确保支持zh_CN.UTF-8;4) 检查SSH服务端配置。完成设置后,重新连接并验证中文显示是否正常。注意字体优先级及系统兼容性,必要时调整环境变量或权限设置。
973 3
【Latex 格式】Markdown或者LaTeX在单个字母上加一横、一点、两点、三角
Markdown或者LaTeX在单个字母上加一横、一点、两点、三角
1954 8
|
Nacos 数据安全/隐私保护
nacos启用鉴权后curl调用接口
nacos启用鉴权后curl调用接口
|
JavaScript 前端开发 搜索推荐
ECharts词云图(案例一)+配置项详解
ECharts,百度的JavaScript图表库,支持词云图(自5.0版起),借助`echarts-wordcloud`插件。配置词云图涉及`tooltip`(如显示、颜色、边框等)和`series`(类型、形状、大小范围等)。示例代码展示了如何在HTML中引入依赖并配置词云图,包括数据、形状、大小、颜色等。完整代码和依赖可下载。调整这些配置可创建个性化词云图。参阅官方文档获取不同版本详情。
6445 4
 ECharts词云图(案例一)+配置项详解
|
安全 Java 数据安全/隐私保护
Spring Boot中的微服务安全架构
Spring Boot中的微服务安全架构
|
编解码 人工智能 自然语言处理
让大模型理解手机屏幕,苹果多模态Ferret-UI用自然语言操控手机
【5月更文挑战第29天】苹果推出Ferret-UI,一个结合图像识别和自然语言处理的多模态大语言模型,允许用户通过自然语言指令操控手机。该系统能适应不同屏幕布局,识别UI元素并执行相应操作,有望变革手机交互方式,提升无障碍体验,并在测试和开发中发挥作用。但需面对屏幕多样性及准确性挑战。[论文链接](https://arxiv.org/pdf/2404.05719.pdf)
806 3