zoukankan      html  css  js  c++  java
  • 《剑指offer》第六十二题(圆圈中最后剩下的数字)

    // 面试题62:圆圈中最后剩下的数字
    // 题目:0, 1, …, n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里
    // 删除第m个数字。求出这个圆圈里剩下的最后一个数字。
    
    #include <iostream>
    #include <list>
    
    using namespace std;
    
    // ====================方法1====================
    //使用环形链表
    int LastRemaining_Solution1(unsigned int n, unsigned int m)
    {
        if (n < 1 || m < 1)//边界判断
            return -1;
    
        unsigned int i = 0;
    
        list<int> numbers;//建立一个链表,值为0~n
        for (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)//找到待删除节点
            {
                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);//上面循环完就剩一个了
    }
    
    // ====================方法2====================
    //需要严谨的数学公式推导,最终得到如下的公式
    int LastRemaining_Solution2(unsigned int n, unsigned 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;
    }
    
    // ====================测试代码====================
    void Test(const char* testName, unsigned int n, unsigned int m, int expected)
    {
        if (testName != nullptr)
            printf("%s begins: 
    ", testName);
    
        if (LastRemaining_Solution1(n, m) == expected)
            printf("Solution1 passed.
    ");
        else
            printf("Solution1 failed.
    ");
    
        if (LastRemaining_Solution2(n, m) == expected)
            printf("Solution2 passed.
    ");
        else
            printf("Solution2 failed.
    ");
    
        printf("
    ");
    }
    
    void Test1()
    {
        Test("Test1", 5, 3, 3);
    }
    
    void Test2()
    {
        Test("Test2", 5, 2, 2);
    }
    
    void Test3()
    {
        Test("Test3", 6, 7, 4);
    }
    
    void Test4()
    {
        Test("Test4", 6, 6, 3);
    }
    
    void Test5()
    {
        Test("Test5", 0, 0, -1);
    }
    
    void Test6()
    {
        Test("Test6", 4000, 997, 1027);
    }
    
    int main(int argc, char* argv[])
    {
        Test1();
        Test2();
        Test3();
        Test4();
        Test5();
        Test6();
        system("pause");
        return 0;
    }
  • 相关阅读:
    TypeScript入门( 一)
    PureComponent: setState未触发render渲染
    再次了解深浅拷贝问题
    关于wepack2.0报错问题
    ES7及ES8的新特性
    闭包
    setState是异步还是同步?
    SQL注入测试之DVWA环境
    i春秋实验--struts2远程命令执行S2-045漏洞利用与修复
    i春秋实验--IIS写权限漏洞利用
  • 原文地址:https://www.cnblogs.com/CJT-blog/p/10547377.html
Copyright © 2011-2022 走看看