<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
        My Github

      劍指Offer面試題:29.丑數(shù)

      一、題目:丑數(shù)

      題目:我們把只包含因子2、3和5的數(shù)稱作丑數(shù)(Ugly Number)。求按從小到大的順序的第1500個丑數(shù)。例如6、8都是丑數(shù),但14不是,因為它包含因子7。習慣上我們把1當做第一個丑數(shù)。

      二、兩種解決方案

      2.1 一一遍歷法:時間效率低下

        使用遍歷法求第k個丑數(shù),從1開始遍歷,如果是丑數(shù)則count++,直到count=k為止。那么如何判斷丑數(shù)呢?根據(jù)丑數(shù)的定義,丑數(shù)只有2,3,5這三個因子,那么我們就拿數(shù)字除以這三個因子。具體算法如下:

      Step1.如果一個數(shù)能夠被2整除,那么讓他繼續(xù)除以2;

      Step2.如果一個數(shù)能夠被3整除,那么讓他繼續(xù)除以3;

      Step3.如果一個數(shù)能夠被5整除,那么讓他繼續(xù)除以5;

      Step4.如果最后這個數(shù)變?yōu)?,那么這個數(shù)就是丑數(shù),否則不是。

        根據(jù)以上算法實現(xiàn)代碼如下:

          public int GetUglyNumber(int index)
          {
              if (index <= 0)
              {
                  return 0;
              }
      
              int number = 0;
              int uglyCount = 0;
      
              while (uglyCount < index)
              {
                  number++;
      
                  if (IsUgly(number))
                  {
                      uglyCount++;
                  }
              }
      
              return number;
          }
      
          private bool IsUgly(int number)
          {
              while (number % 2 == 0)
              {
                  number /= 2;
              }
      
              while (number % 3 == 0)
              {
                  number /= 3;
              }
      
              while (number % 5 == 0)
              {
                  number /= 5;
              }
      
              return number == 1 ? true : false;
          }

        該算法非常直觀,代碼也非常簡潔,但最大的問題就在于每個整數(shù)都需要計算。即使一個數(shù)字不是丑數(shù),我們還是需要對它做求余數(shù)和除法操作。因此該算法的時間效率不是很高,

      2.2 空間換時間法:時間效率較高

        根據(jù)丑數(shù)的定義,我們可以知道丑數(shù)可以由另外一個丑數(shù)乘以2,3或者5得到。因此我們可以創(chuàng)建一個數(shù)組,里面的數(shù)字是排好序的丑數(shù),每一個丑數(shù)都是前面的丑數(shù)乘以2,3或者5得到的。

        我們把得到的第一個丑數(shù)乘以2以后得到的大于M的結果記為M2。同樣,我們把已有的每一個丑數(shù)乘以3和5,能得到第一個大于M的結果M3和M5。那么M后面的那一個丑數(shù)應該是M2,M3和M5當中的最小值:Min(M2,M3,M5)。比如將丑數(shù)數(shù)組中的數(shù)字按從小到大乘以2,直到得到第一個大于M的數(shù)為止,那么應該是2*2=4<M,3*2=6>M,所以M2=6。同理,M3=6,M5=10。所以下一個丑數(shù)應該是6。

        根據(jù)以上思路實現(xiàn)代碼如下:

          public int GetUglyNumber(int index)
          {
              if (index <= 0)
              {
                  return 0;
              }
      
              int[] uglyNumbers = new int[index];
              uglyNumbers[0] = 1;
              int nextUglyIndex = 1;
      
              int multiply2 = 0;
              int multiply3 = 0;
              int multiply5 = 0;
              int min = 0;
      
              while (nextUglyIndex < index)
              {
                  min = Min(uglyNumbers[multiply2] * 2, uglyNumbers[multiply3] * 3, uglyNumbers[multiply5] * 5);
                  uglyNumbers[nextUglyIndex] = min;
      
                  while (uglyNumbers[multiply2] * 2 <= uglyNumbers[nextUglyIndex])
                  {
                      multiply2++;
                  }
      
                  while (uglyNumbers[multiply3] * 3 <= uglyNumbers[nextUglyIndex])
                  {
                      multiply3++;
                  }
      
                  while (uglyNumbers[multiply5] * 5 <= uglyNumbers[nextUglyIndex])
                  {
                      multiply5++;
                  }
      
                  nextUglyIndex++;
              }
      
              int result = uglyNumbers[index - 1];
              uglyNumbers = null;
      
              return result;
          }
      
          private int Min(int num1, int num2, int num3)
          {
              int min = num1 < num2 ? num1 : num2;
              min = min < num3 ? min : num3;
      
              return min;
          }

        和第一種方案相比,第二種方案不需要在非丑數(shù)的整數(shù)上做任何計算,因此時間效率有明顯提升。但也需要指出,第二種算法由于需要保存已經(jīng)生成的丑數(shù),因此需要一個數(shù)組,從而增加了空間消耗。如果是求第1500個丑數(shù),將創(chuàng)建一個能容納1500個丑數(shù)的數(shù)組,這個數(shù)組占內(nèi)存6KB。

      三、單元測試與性能對比

      3.1 單元測試

       ?。?)測試用例

          public static void Main(string[] args)
          {
              Program p = new Program();
              p.Test(1);
              p.Test(2);
              p.Test(3);
              p.Test(4);
              p.Test(5);
              p.Test(6);
              p.Test(7);
              p.Test(8);
              p.Test(9);
              p.Test(10);
              p.Test(11);
              p.Test(1500);
              p.Test(0);
              p.Test(1500);
      
              Console.ReadKey();
          }
      
          public void Test(int index)
          {
              int result = GetUglyNumberWithSpace(index);
              Console.WriteLine("Test result is {0}", result);
              Console.WriteLine("-------------End-------------");
          }
      View Code

        (2)測試結果

      3.2 性能對比

        這里我們使用兩種解決方案來求第1500個丑數(shù),通過下面的圖片可以清楚地看到兩種方案的響應時間。(這里借助老趙的CodeTimer類來進行時間效率的監(jiān)測)

       ?。?)一一遍歷法:65秒,等得花兒都謝了

        

        (2)空間換時間法:4毫秒,迅雷不及掩耳

        

        由對比可以看出,一個簡單的優(yōu)化,再通過6KB的空間換取了巨大的時間效率,在實際開發(fā)中是一個值得實踐的解決思路(當然,事先得權衡一下利弊)。

       

      posted @ 2015-09-13 16:57  EdisonZhou  閱讀(11284)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 欧美自拍嘿咻内射在线观看| 国产精品爆乳奶水无码视频免费 | 熟女一区| 在线精品自拍亚洲第一区| 亚洲人亚洲人成电影网站色| 亚洲欧洲日产国码无码久久99 | 高清国产精品人妻一区二区| 亚洲欧洲日产国产av无码| 亚洲av天堂天天天堂色| 亚洲精品日韩在线丰满| 制服 丝袜 亚洲 中文 综合| 韩国午夜福利片在线观看| 丁香五月婷激情综合第九色| 国产成a人亚洲精v品无码性色| 成人无码区在线观看| 亚洲最大成人av免费看| 99在线小视频| 美女黄网站人色视频免费国产| 国产成人无码A区在线观看视频| 亚洲成人午夜排名成人午夜| 波多野结系列18部无码观看AV| 日韩深夜福利视频在线观看| 国产精品成人一区二区不卡| 国产午夜精品福利视频| 在线中文字幕国产一区| 99福利一区二区视频| 宜都市| 久久精品午夜视频| 国产无码高清视频不卡| 一区二区亚洲精品国产精| 亚洲人成网站免费播放| 亚洲熟妇久久精品| 一 级做人爱全视频在线看| 日本欧美大码a在线观看| 日本一区二区不卡精品| 国产精品无码素人福利不卡| 亚洲色欲在线播放一区二区三区| 亚洲欧美牲交| 丁香花在线观看免费观看图片| 亚洲AV乱码毛片在线播放| 亚洲丰满熟女一区二区蜜桃|