zoukankan      html  css  js  c++  java
  • JZ-C-45

    剑指offer第四十五题:圆圈中最后剩下的数字:0,1,..,n-1这n个数排成一个圆圈,从数字0开始每次从圆圈中删除第m个数字。求出圆圈中剩下的最后一个数字(约瑟夫环★)

      1 //============================================================================
      2 // Name        : JZ-C-45.cpp
      3 // Author      : Laughing_Lz
      4 // Version     :
      5 // Copyright   : All Right Reserved
      6 // Description : 圆圈中最后剩下的数字:0,1,..,n-1这n个数排成一个圆圈,从数字0开始每次从圆圈中删除第m个数字。求出圆圈中剩下的最后一个数字(约瑟夫环★)
      7 //============================================================================
      8 
      9 #include <iostream>
     10 #include <stdio.h>
     11 #include <list>
     12 using namespace std;
     13 
     14 // ====================方法1====================
     15 /**
     16  * 使用环形链表模拟圆圈,这里用模板库的std::list模拟环形链表,当迭代器扫描到链表末尾时候,将迭代器移到链表的头部
     17  * 每删除一个数字都需要m步运算,共n个数字,所以时间复杂度为O(m*n),并且还需要一个辅助链表模拟圆圈,所以空间复杂度为O(n)
     18  */
     19 int LastRemaining_Solution1(unsigned int n, unsigned int m) {
     20     if (n < 1 || m < 1)
     21         return -1;
     22     unsigned int i = 0;
     23 
     24     list<int> numbers;
     25     for (i = 0; i < n; ++i)
     26         numbers.push_back(i);
     27 
     28     list<int>::iterator current = numbers.begin();
     29     while (numbers.size() > 1) {
     30         for (int i = 1; i < m; ++i) { //m也可以为1
     31             current++;
     32             if (current == numbers.end()) //当迭代器扫描到链表末尾时候,将迭代器移到链表的头部
     33                 current = numbers.begin();
     34         }
     35 
     36         list<int>::iterator next = ++current;
     37         if (next == numbers.end()) //当迭代器扫描到链表末尾时候,将迭代器移到链表的头部
     38             next = numbers.begin();
     39 
     40         --current;
     41         numbers.erase(current);
     42         current = next;
     43     }
     44 
     45     return *(current);
     46 }
     47 
     48 // ====================方法2====================
     49 /**
     50  * n>1时:f(n,m) = [f(n-1,m)+m]%n;
     51  * n=1时:f(n,m) = 0;
     52  * 这种算法的时间复杂度为O(n),空间复杂度为O(1)
     53  * 求解释!!!★★★
     54  */
     55 int LastRemaining_Solution2(unsigned int n, unsigned int m) {
     56     if (n < 1 || m < 1)
     57         return -1;
     58 
     59     int last = 0;
     60     for (int i = 2; i <= n; i++)
     61         last = (last + m) % i;
     62 
     63     return last;
     64 }
     65 
     66 // ====================测试代码====================
     67 void Test(char* testName, unsigned int n, unsigned int m, int expected) {
     68     if (testName != NULL)
     69         printf("%s begins: 
    ", testName);
     70 
     71     if (LastRemaining_Solution1(n, m) == expected)
     72         printf("Solution1 passed.
    ");
     73     else
     74         printf("Solution1 failed.
    ");
     75 
     76     if (LastRemaining_Solution2(n, m) == expected)
     77         printf("Solution2 passed.
    ");
     78     else
     79         printf("Solution2 failed.
    ");
     80 
     81     printf("
    ");
     82 }
     83 
     84 void Test1() {
     85     Test("Test1", 5, 3, 3);
     86 }
     87 
     88 void Test2() {
     89     Test("Test2", 5, 2, 2);
     90 }
     91 
     92 void Test3() {
     93     Test("Test3", 6, 7, 4);
     94 }
     95 
     96 void Test4() {
     97     Test("Test4", 6, 6, 3);
     98 }
     99 
    100 void Test5() {
    101     Test("Test5", 0, 0, -1);
    102 }
    103 
    104 void Test6() {
    105     Test("Test6", 4000, 997, 1027);
    106 }
    107 
    108 int main(int argc, char** argv) {
    109     Test1();
    110     Test2();
    111     Test3();
    112     Test4();
    113     Test5();
    114     Test6();
    115     return 0;
    116 }
  • 相关阅读:
    PTA(Basic Level)1038.统计同成绩学生
    PTA(Basic Level)1026.程序运行时间
    PTA(Basic Level)1031.查验身份证
    PTA(Basic Level)1061.判断题
    Windows 常用命令
    Windows安装启动MySQL
    classpath路径配置
    IDEA远程调试
    Java Effective 读书笔记
    Try Catch Finally总结
  • 原文地址:https://www.cnblogs.com/Laughing-Lz/p/5615278.html
Copyright © 2011-2022 走看看