循环链表的约瑟夫问题(牛客)——C语言解决

循环链表的约瑟夫问题描述

编号为 1 到 n 的 n 个人围成一圈。从编号为 1 的人开始报数,报到 m 的人离开。

下一个人继续从 1 开始报数。

n-1 轮结束以后,只剩下一个人,问最后留下的这个人编号是多少?

数据范围: 1 ≤ n,m≤10000

进阶:空间复杂度 O(1),时间复杂度 O(n)

示例一:

输入:5,2

返回值:3

说明:

开始5个人 1,2,3,4,5 ,从1开始报数,1->1,2->2编号为2的人离开
1,3,4,5,从3开始报数,3->1,4->2编号为4的人离开
1,3,5,从5开始报数,5->1,1->2编号为1的人离开
3,5,从3开始报数,3->1,5->2编号为5的人离开
最后留下人的编号是3      

示例二:

输入:1,1

返回值:1

我们拿示例一做示范黑色为每个人的编号,有5个人,喊道2的人离场(绿色为该人的报道数),继续从一报数,直到剩一人为止。

最后只剩下编号为3 的人。

解题思路:

1.创建一个循环链表,每个节点上的值就为其节点的编号。

2.创建循环过程,用一个count作为计数器,当count==m时,实行链表节点删除,直到剩下一个人为止。

代码

typedef struct SListNode {
    int val;
    struct SListNode*next;
}SLNode;

SLNode* BuyNode(int i)//创建节点
{
    SLNode* tmp=(SLNode*)malloc(sizeof(SLNode));
    if(tmp == NULL)
    {
        perror("malloc fail!\n");
        exit(1);
    }
    tmp->val = i;//i就是链表节点的编号
    tmp->next = NULL;
    return tmp;
}
SLNode* CreatList(int n)//创建n个节点的环形链表
{
    SLNode* phead = BuyNode(1);
    SLNode* ptail = phead;
    for(int i = 2;i <= n; i++)
    {
        SLNode* pcur=BuyNode(i);
        ptail->next= pcur;
        ptail= ptail->next;
    }
    //联成环
    ptail->next=phead;
    return ptail;//后续需要尾节点和头节点 
}


int ysf(int n, int m ) //主体函数
{
    SLNode* prev=CreatList(n);
    SLNode* pcur=prev->next;
    int count=1;
    while(pcur->next!=pcur)//最后只剩一个人,pcur->next=pcur
    {   
        if(count == m)
        {
            //count=m,实施链表节点的删除
            SLNode* next=pcur->next;
            prev->next= next;
            free(pcur);
            pcur=next;
            count = 1;
        }
        else
        {
            prev = pcur;
            pcur = pcur->next;
            count++;
        }
    }
//返回最后编号
    return pcur->val;
}

这个博客如果对你有帮助,给博主一个免费的点赞就是最大的帮助

欢迎各位点赞,收藏和关注哦

如果有疑问或有不同见解,欢迎在评论区留言哦

后续我会一直分享双一流211西北大学软件(C,数据结构,C++,Linux,MySQL)的学习干货以及重要代码的分享

  • 21
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一码归—码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值