数据结构-剑指offer-圆圈中最后剩下的数字

题目:0,1,...,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈中删掉第m个数字。求出这个圆圈里剩下的最后一个数字。(牛客上bulabulabula说了一堆)

思路:本质上是一个环的问题,可以使用环形链表

剑指offer思路1:用环形链表模拟圆圈。创建一个共有n个节点的环形链表,然后每次在这个链表中删除第m个节点。可以使用模板库中的std::list来模拟一个环形链表,由于每当迭代器(Iterator)扫描到链表末尾的时候,要把迭代器移到链表的头部,这样就相当于按照顺序在一个圆圈里遍历了。照着打了一遍竟然都没有通过任何测试用例。。。。。

class Solution {
public:
    int LastRemaining_Solution(unsigned int n, unsigned int m)
    {
        if(n<1 || m<1) return -1;
        unsigned int i = 0;
        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=0; i<m; ++i){
                current ++;
                if(current == numbers.end())
                    current = numbers.begin();
            }
            list<int>::iterator next = ++current;
            if(next == numbers.end())
                next = numbers.begin();
            --current;
            numbers.erase(current);
            current = next;
        }
        return *(current);
    }
};

剑指offer思路2:找规律,定义一个关于函数n和m的方程f(m,n),表示每次在n个数字0,,1,...,n-1中删除第m个数字最后剩下的数字。在这n个数字中,第一个被删除的数字是(m-1)%n. 把(m-1)%n记为k,那么删除k之后剩下的n-1个数字为0,1,...,k-1,k+1,...,n-1,并且下一次删除从数字k+1开始计数。相当于在剩下的序列中,k+1排在最前面,从而形成k+1,..,n-1,0,1,...,k-1. 该序列最后剩下的数字也应该是关于n和m的函数,每删除一个数后,数列的总数就会减一,所以f(n-1,m),已经对前m个进行了判断,所以[f(n-1,m)+m]%n.

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

使用队列模拟循环。队列跟数组比的好处是,可以不用考虑下标。用的时间是公式法的7倍左右,时间复杂度很高。

class Solution {
public:
    int LastRemaining_Solution(int n, int m)
    {
        if(n<1 || m<1) return -1;
        queue<int> result;
        for(int i=0;i<n;i++)
            result.push(i);
        while(result.size() != 1){
            for(int i=0;i<m-1;i++){
                int temp = result.front();
                result.pop();
                result.push(temp);
            }
            result.pop();
        }
        return result.front();
    }
};

猜你喜欢

转载自blog.csdn.net/baidu_32936911/article/details/80684400