zoukankan      html  css  js  c++  java
  • 剑指offer-约瑟夫环

    题目:

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

    很经典的约瑟夫环问题。

    一个很自然的想法是建立循环链表,利用链表模拟游戏过程:

    方案一(链表):

    class Solution {
        struct CircNode{
            int val;
            struct CircNode* next;
            CircNode(int x):val(x),next(NULL){};
        };
    public:
        int Joseph(CircNode* head, int m)
        {
    	    CircNode* pre = NULL;
    	    while (head->next != head)
    	    {
    		    for (int i = 0; i < m - 1; i++)
    		    {
    			    pre = head;
    			    head = head->next;
    		    }
    		    pre->next= head->next;
    		    delete head;
    		    head = pre->next;
    	    }
    	    return head->val;
        }
        int LastRemaining_Solution(int n, int m)
        {
            if(n<=0) return -1;
    	    CircNode* head = new CircNode(0), *p = head;
    	    head->next = head;
    	    for (int i = 1; i<n; i++)
    	    {
    		    CircNode* temp = new CircNode(i);
    		    p->next = temp;
    		    temp->next = head;
    		    p = p->next;
    	    }
    	    return Joseph( head,m);
        }
    };

    也可以直接利用C++STL中的顺序容器list,注意list中封装的是双向链表,且其支持的迭代子为双向迭代子,迭代子仅能进行++、--操作。

    class Solution {
    public:
        int LastRemaining_Solution(int n, int m)//n为人数
        {
            if(n<1||m<1)
                return -1;
            list<int> numbers;
            for(int i=0;i<n;i++)
                numbers.push_back(i);
            list<int>::iterator current=numbers.begin();
            while(numbers.size()>1)
            {
                for(int i=1;i<m;i++)//走m-1步到达第m个数处
                {
                    ++current;
                    if(current==numbers.end())
                        current=numbers.begin();
                }
                list<int>::iterator next=++current;
                if(next==numbers.end())
                    next=numbers.begin();
                numbers.erase(--current);
                current=next;
            }
            return *current;//对迭代器取值,等价于对指针取值
        }
    };

    方案二(数组):

    class Solution {
    public:
        int LastRemaining_Solution(int n, int m)
        {
            if (n <= 0) return -1;
    	    if (n == 1) return 0;
    	    int* Joseph = new int[n];
    	    for (int i = 0; i<n; i++)
    		    Joseph[i] = i;
    	    int index = 0;
    	    for (int i = 0; i<n - 1; i++)
    	    {
    		    int count = m - 1;
    		    while (count)
    		    {
    			    index = (index + 1) % n;
    			    if (Joseph[index] == -1) continue;
    			    count--;
    		    }
    		    Joseph[index] = -1;
    		    while (Joseph[index] == -1) index = (index + 1) % n;
    	    }
    	    return Joseph[index];
        }
    };

    方案三:

    class Solution {
    public:
        int LastRemaining_Solution(int n, int m)
        {
            if(n<=0) return -1;
            return n==1? 0:(LastRemaining_Solution(n-1,m)+m)%n;
        }
    };

    方案四:

    该方案作为方案三尾递归的循环形式

    class Solution {
    public:
        int LastRemaining_Solution(int n, int m)
        {
            if(n<=0) return -1;
            if(n==1) return 0;
            int res=0;
            for(int i=2;i<=n;i++)
            {
                res=(res+m)%i;
            }
            return res;
        }
    };

    参考:https://www.nowcoder.com/questionTerminal/f78a359491e64a50bce2d89cff857eb6

               https://www.nowcoder.com/questionTerminal/11b018d042444d4d9ca4914c7b84a968

               

  • 相关阅读:
    ES6知识点整理之----async----异步遍历器
    ES6知识点整理之----async----实现原理以及与其他异步的比较
    ES6知识点整理之----async----语法
    ES6知识点整理之----async----含义及基本用法
    ES6知识点整理之----Generator----异步
    ES6知识点整理之----Generator----其他
    ES6知识点整理之----Generator----yield*表达式
    ES6知识点整理之----Generator----API
    ES6知识点整理之----Generator----next与for...of
    ES6知识点整理之----Generator----概述
  • 原文地址:https://www.cnblogs.com/oneDongHua/p/14264024.html
Copyright © 2011-2022 走看看