当前位置:首页 > 牛客 > 牛客3407题解:用递推破解约瑟夫环

牛客3407题解:用递推破解约瑟夫环

1个月前 (08-11)

牛客3407题解:用递推破解约瑟夫环 牛客题解 约瑟夫环 递推 C++ 环形结构 第1张

一、题目解读

牛客3407题(约瑟夫环问题)要求n个人围成环,从第1个人开始报数,报到m的人出列,重复直至剩最后一人。用户提供的代码通过递推公式直接计算最后幸存者的编号,避免了传统环形链表模拟的高复杂度,实现高效求解。

二、解题思路

核心思想为:

1. 数学建模:将问题转化为递推关系,利用数学归纳法推导公式;

2. 递推公式:定义f(n,m)为n人环中最后幸存者编号,则f(n,m) = (f(n-1,m) + m) % n;

3. 边界条件:当n=1时,唯一幸存者编号为0(即第1人),递推由此展开;

4. 优化逻辑:通过取模运算避免数组模拟,直接计算最终结果。

三、解题步骤

1. 输入校验:若n或m非法(<1),返回-1;

2. 初始化:设置last=0(即f(1,m)=0);

3. 递推循环:从i=2到n,执行last = (last + m) % i,模拟人数递增时的幸存者编号变化;

4. 结果返回:循环结束后,last即为最终答案。

四、代码与注释

class Solution {
public:
    int LastRemaining_Solution(int n, int m) {
        if (n < 1 || m < 1) return -1; // 处理非法输入
        int last = 0; // n=1时的解
        // 递推公式:f(n,m)=(f(n-1,m)+m)%n
        for (int i = 2; i <= n; ++i) {
            last = (last + m) % i;
        }
        return last; // 返回最后剩下的数字
    }
};

五、总结

本解法通过递推公式将复杂的环形淘汰问题转化为线性计算,时间复杂度O(n),空间复杂度O(1)。关键在于理解递推关系的数学本质,避免传统模拟带来的高开销。适用于需要高效求解约瑟夫环问题的场景,展示了算法设计中“化繁为简”的巧妙思路。


原创内容 转载请注明出处

分享给朋友:

相关文章

线性遍历+二进制 6行代码征服二进制链表转整数

线性遍历+二进制 6行代码征服二进制链表转整数

力扣1290.二进制链表转整数题目本质给定一个单链表的头节点head,链表中每个节点的值为0或1。链表表示一个‌最高有效位在前‌的二进制数字,要求将其转换为对应的十进制整数。例如链表1→0→1对应的二...

力扣654:递归分治的艺术 如何用最大元素构建二叉树

力扣654:递归分治的艺术 如何用最大元素构建二叉树

题目重解我们面对一个看似简单却充满递归魅力的题目:给定一个不含重复元素的整数数组,需要构建一棵特殊的二叉树。这个树的每个父节点都必须是当前子数组中的最大元素,而它的左右子树则分别由该最大值左侧和右侧的...

力扣933题:队列的妙用:如何高效统计最近请求

力扣933题:队列的妙用:如何高效统计最近请求

题目重解:我们需要设计一个能统计最近3000毫秒内请求次数的系统。每当新的请求到来时,它会带有时间戳t,我们需要返回过去3000毫秒内(包括当前)发生的请求总数。这就像是在时间轴上维护一个滑动窗口,只...

手搓顺序表类代码注释与详解:从零实现动态数组(新手教程)

一、简介和特点顺序表(Sequential List)是数据结构中基础的一种线性表,其特点是将数据元素存储在连续的内存空间中。通过数组实现,支持随机访问(即通过索引直接访问元素),适用于频繁随机读取的...

力扣3112题解法:带时间限制的最短路径问题解析(C++代码)

力扣3112题解法:带时间限制的最短路径问题解析(C++代码)

一、题目解读力扣3112题要求解决带时间限制的最短路径问题:给定一个有向图,节点具有消失时间,需计算从起点到各节点的最短路径,且路径总时间不能超过节点的消失时间。题目难点在于需在传统最短路径算法(如D...

洛谷1220题解:动态规划与区间DP优化解法(附代码注释)

洛谷1220题解:动态规划与区间DP优化解法(附代码注释)

一、题目解读洛谷1220题要求计算在n个位置放置灯的情况下,通过关闭连续区间灯并移动至区间端点,使得总耗电量最小。需考虑灯的功率与位置差异,设计高效的算法求解最优策略。二、解题思路1. 动态规划 +...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。