JZ-C-45

劍指offer第四十五題:圓圈中最後剩下的數字:0,1,..,n-1這n個數排成一個圓圈,從數字0開始每次從圓圈中刪除第m個數字。求出圓圈中剩下的最後一個數字(約瑟夫環★)ios

  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: \n", testName);
 70 
 71     if (LastRemaining_Solution1(n, m) == expected)
 72         printf("Solution1 passed.\n");
 73     else
 74         printf("Solution1 failed.\n");
 75 
 76     if (LastRemaining_Solution2(n, m) == expected)
 77         printf("Solution2 passed.\n");
 78     else
 79         printf("Solution2 failed.\n");
 80 
 81     printf("\n");
 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 }
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息