劍指offer之【醜數】☆
題目:
醜數
鏈接:
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個醜數。
思路:
試圖只計算醜數,而不在非醜數的整數上花費時間。根據醜數的定義,醜數應該是另一個醜數乘以2、3或者5的結果(1除外)。因此我們可以創建一個數組,裏面的數字是排好序的醜數。裏面的每一個醜數是前面的醜數乘以2、3或者5得到的。
這種思路的關鍵在於怎樣確保數組裏面的醜數是排好序的。我們假設數組中已經有若幹個醜數,排好序後存在數組中。我們把現有的最大醜數記做M。現在我們來生成下一個醜數,該醜數肯定是前面某一個醜數乘以2、3或者5的結果。我們首先考慮把已有的每個醜數乘以2。在乘以2的時候,能得到若幹個結果小於或等於M的。由於我們是按照順序生成的,小於或者等於M肯定已經在數組中了,我們不需再次考慮;我們還會得到若幹個大於M
前面我們分析的時候,提到把已有的每個醜數分別都乘以2、3和5,事實上是不需要的,因為已有的醜數是按順序存在數組中的。對乘以2而言,肯定存在某一個醜數T2,排在它之前的每一個醜數乘以2得到的結果都會小於已有最大的醜數,在它之後的每一個醜數乘以2得到的結果都會太大。我們只需要記下這個醜數的位置,同時每次生成新的醜數的時候,去更新這個T2
代碼:
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之【醜數】☆