【C++代码】约瑟夫环问题:0,1,……,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。

问题描述:0,1,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。

       

这是力扣上的一道题。我的思路:

  • ①首先想到的是用循环链表,每次向后遍历找到第m个节点,从链表中删除,再找下一个第m个节点再删除,直到链表中剩下一个节点。但是链表不支持随机访问,每次访问往后的第m个结点也是很费时的。
           
  • ②然后想到用数组,数组支持随机读取,可以直接通过下标访问下一个第m个节点,但删除一个元素后,移动剩下元素要耗费大量时间。
           
  • ③那有没有用数组但又不删除元素的方法呢。每删除一个数,就把这个元素值置为-1,每经过m个不为-1的数,就把这个数值置为-1,直到数组中只剩下一个不为-1的元素,这个元素值就是答案。(这种方法效率和链表比起来也差不多)
           
    第③种方法虽然有数组的随机访问速度,也不用删除元素,但数据量大的时候,运行到后面数组内有大量值为-1的元素,要进行多次循环判断,速度也很慢,提交后直接超时。官方给出的是数学方法,找出问题的递归公式,几行代码解决。
           
  • ④数学方法(递推公式为 f(N,M)=(f(N−1,M)+M)%N ),数学公式如何推出来的见博客约瑟夫环——公式法(递推公式)

       
       

附上代码:

第①中方法(使用链表):

// 定义链表的节点
struct node{
   
    int val;
    node *next;
    node(int val_,node *next_=nullptr){
   
        val=val_;
        next=next_;
    }
};

class Solution {
   
public:
    int LastRemaining_Solution(int n, int m){
   
        if(n<=0 || m<=0)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值