zoukankan      html  css  js  c++  java
  • [剑指Offer]62-圆圈中最后剩下的数(约瑟夫环问题)(法二待做)

    题目链接

    https://www.nowcoder.com/practice/f78a359491e64a50bce2d89cff857eb6?tpId=13&tqId=11199&tPage=3&rp=3&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

    题目描述

    每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!_)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)

    解题思路

    方法一:模拟,使用list实现循环链表。时间复杂度O(mn)
    方法二:公式。

    相关知识

    1 C++ STL list :底层用双向链表实现。所以底层存储不连续!!!所以迭代器不能+2之类的这种!要得到后面元素的地址,删掉元素前也要提前保存指向后面的元素的迭代器!
    2 因为迭代器++,要时刻注意是否非法访问!

    代码

    方法一:

    class Solution {
    public:
        int LastRemaining_Solution(int n, int m)
        {
            list<int> circle;
            if(n<1||m<1){
                return -1;
            }
            for(int i=0;i<n;i++){
                circle.push_back(i);
            }
            
            list<int>::iterator it=circle.begin();
            while(circle.size()!=1){
                int step=m-1;
                while(step--){
                    if(it==circle.end()){
                        it=circle.begin();
                    }
                    ++it;
                }
                if(it==circle.end()){
                    it=circle.begin();
                }
                list<int>::iterator next=++it;
                --it;
                circle.erase(it);
                it=next;
            }
            return circle.front();
        }
    };
    

    方法二:

  • 相关阅读:
    面向对象——多态
    面向对象——继承
    面向对象—封装
    数组
    控制语句
    认识Java
    出入境大厅流程
    2021上半年感想
    记录2020
    读后感《从三分钟热度到一万个小时》
  • 原文地址:https://www.cnblogs.com/coding-gaga/p/10525613.html
Copyright © 2011-2022 走看看