程序员代码面试指南 2.6:环形链表的约瑟夫问题

解法一

1、思路

  • 遍历环形链表,删除每 m 个节点,直到链表中剩下一个元素为止;

  • 一共要删除 n - 1 个节点,每次删除要遍历 m 次,时间复杂度为 ,略高。

2、代码

#include <iostream>
#include <memory>

using namespace std;

struct ListNode                         //单链表结构体
{
    int val;
    shared_ptr<ListNode> next;
    ListNode(int _val) : val(_val), next(nullptr) {}
};

shared_ptr<ListNode> createList(int n)  //构造环形链表
{
    shared_ptr<ListNode> head = make_shared<ListNode>(0);
    auto p = head;

    for (int i = 1; i <= n; ++ i)
    {
        p = p->next = make_shared<ListNode>(i);
    }

    p->next = head->next;
    return head->next;
}

//约瑟夫环问题,每次删去环中第m个节点
shared_ptr<ListNode> josephusKill(shared_ptr<ListNode> head, int m)
{
    if (head == nullptr || head->next == head || m < 1) return head;

    auto last = head;
    while (last->next != head)  //保存最后一个节点
    {
        last = last->next;
    }

    int cnt = 0;
    while (head != last)        //当 head == last 时,链表中只剩下一个节点了
    {
        if ( ++ cnt == m)       //跳过每 m 个节点
        {
            last->next = last->next->next;
            cnt = 0;
        }
        else
        {
            last = last->next;
        }

        head = last->next;
    }

    return head;
}

int main()
{
    int n, m;
    cin >> n >> m;

    shared_ptr<ListNode> head = createList(n);

    while (head->next->val != head->val)    //循环删除,直到剩下一个节点为止
    {
        head = josephusKill(head, m);
    }

    cout << head->val << endl;

    return 0;
}

主要是为左程云的《程序员代码面试指南》这本书改写C++版的题解。

全部评论

相关推荐

点赞 评论 收藏
分享
希望被捞的猫头鹰很理智:大概率待遇低怕硕士跑路
点赞 评论 收藏
分享
03-28 14:34
中南大学 Java
网易互娱明天的笔试是在一天之内任意选时间作答,那不就等于说可以抄答案?那为什么要发笔试?美团也说不拿笔试卡人,那为什么要发笔试?觉得学生们很有时间是吗?&nbsp;还有那些笔试全A了没有进面的,笔试的意义到底在哪里?
no_work_no_life:网易互娱的笔试本来就很简单 美团的确实不按笔试刷人,但是笔试是捞人的重要依据,尤其对于双非学生……我一面的时候面试官直接说是看我笔试成绩还可以就把我捞起来了……
投递美团等公司6个岗位 >
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务