1. 程式人生 > >劍指offer之【醜數】☆

劍指offer之【醜數】☆

下一個 一個數 ice amp spa public cto interview 但我

題目:

  醜數

鏈接:

  https://www.nowcoder.com/practice/6aa9e04fc3794f68acf8778237ba065b?tpId=13&tqId=11186&tPage=2&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking

題目描述:

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

思路:

  試圖只計算醜數,而不在非醜數的整數上花費時間。根據醜數的定義,醜數應該是另一個醜數乘以23或者5的結果(1除外)。因此我們可以創建一個數組,裏面的數字是排好序的醜數。裏面的每一個醜數是前面的醜數乘以23或者5得到的。

  這種思路的關鍵在於怎樣確保數組裏面的醜數是排好序的。我們假設數組中已經有若幹個醜數,排好序後存在數組中。我們把現有的最大醜數記做M。現在我們來生成下一個醜數,該醜數肯定是前面某一個醜數乘以23或者5的結果。我們首先考慮把已有的每個醜數乘以2。在乘以2的時候,能得到若幹個結果小於或等於M的。由於我們是按照順序生成的,小於或者等於M肯定已經在數組中了,我們不需再次考慮;我們還會得到若幹個大於M

的結果,但我們只需要第一個大於M的結果,因為我們希望醜數是按從小到大順序生成的,其他更大的結果我們以後再說。我們把得到的第一個乘以2後大於M的結果,記為M2。同樣我們把已有的每一個醜數乘以35,能得到第一個大於M的結果M3M5。那麽下一個醜數應該是M2M3M5三個數的最小者。

  前面我們分析的時候,提到把已有的每個醜數分別都乘以235,事實上是不需要的,因為已有的醜數是按順序存在數組中的。對乘以2而言,肯定存在某一個醜數T2,排在它之前的每一個醜數乘以2得到的結果都會小於已有最大的醜數,在它之後的每一個醜數乘以2得到的結果都會太大。我們只需要記下這個醜數的位置,同時每次生成新的醜數的時候,去更新這個T2

。對乘以35而言,存在著同樣的T3T5

代碼:

  

 1 class Solution {
 2 public:
 3     int GetUglyNumber_Solution(int index){
 4         if(index < 7)
 5               return index;
 6         vector<int> res(index);
 7         res[0]=1;
 8         int t2 =0,t3 = 0, t5 = 0,i;
 9         for(i = 1;i<index;++i)
10         {
11             res[i] = min(res[t2]*2,min(res[t3]*3,res[t5]*5));
12             if(res[i] == res[t2]*2){
13                 ++t2;
14             }
15             if(res[i] == res[t3]*3){
16                 ++t3;
17             }
18             if(res[i] == res[t5]*5){
19                 ++t5;
20             }
21         }
22         return res[index-1];
23     }
24 };

劍指offer之【醜數】☆