找到第1500個醜數

2021-10-07 23:23:27 字數 1721 閱讀 2621

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

暴力的一點的方法, 可以從1開始遍歷, 依次判斷是否是醜數, 如果是醜數, 計數器+1, 當計數器加到1500的時候, 這個數字就是醜數了.

- (void)viewdidload 

// 找到醜數

- (void)finduglynum

num++;

}// 第1500個 859963392

nslog(@"結束%@",array.lastobject);

}- (bool)isuglynum:(nsinteger)num

while (num%3==0)

while (num%5==0)

return num == 1;

}

在實際執行的過程中, 前1000個計算還是很快的, 到1000之後計算間隔就能明顯的感覺到了, 計算第1500個需要用時1分20秒左右. 時間複雜度的話,  需要從1到859963392次遍歷 , 每次遍歷判斷是否為醜數是logn級別的, 總體時間複雜度不太好衡量. 

每個醜數都可以分解成任意個2, 3, 5的組合乘積,   

任意乙個醜數 = (2^n2) * (3^n3) * (5^n5)

= (2^n2-1) * (3^n3) * (5^n5) * 2 = 前面某個醜數 * 2

= (2^n2) * (3^n3-1) * (5^n5) * 3 = 前面某個醜數 * 3

= (2^n2) * (3^n3) * (5^n5-1) * 5 = 前面某個醜數 * 5

根據這個, 我們根據前面的醜數生成後面的醜數, 避免每次都進行判斷是否為醜數. 可以就有乙個問題, 比如10後面的數字有很多, 怎麼判斷生成的那個醜數是比10大一點點,  而沒有超過其他醜數呢?  我們可以通過前面的醜數*2生成t2max,  前面的某個醜數*3生成t3max , 前面的某個醜數 * 5生成t5max,  然後取 t2max, t3max,  t5max中的最小值 , 那麼這個就是下乙個醜數了 , 不斷迴圈, 直到找到第1500個.

- (void)viewdidload 

// 找到醜數, 優化

- (void)finduglynum2

while (t3max<=currentmax)

while (t5max<=currentmax)

int nextvalue = min(t2max, min(t3max, t5max) );

[array addobject:@(nextvalue)];

nslog(@"第%lu個 %d",(unsigned long)array.count,nextvalue);

}// 859963392

nslog(@"結果 : %@",array.lastobject);

這個演算法的時間可以再毫秒內完成, 時間複雜度是o(n), 需要乙個額外的空間o(n).

尋找第1500個醜數

諾西筆試最後一道題,題意 把只包含質因子2 3和5的數稱作醜數 ugly number 例如 2,3,4,5,6,8,9,10,12,15,等,習慣上我們把1當做是第乙個醜數。寫乙個高效演算法,返回第n個醜數。最普通 也最耗時 的做法是從1開始遍歷,然後判斷這個數的因式分解中只包含2,3,5,滿足則...

找到第N個醜數

把只包含因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。找到第n個醜數 方法1 存放num之前所有元素是否是醜數的flag int getuglynumber solution in...

83 找到第n個醜數

2,3,5 6 是醜數 14 不是醜數,包含7 下乙個醜數必定是陣列的某乙個醜數a 2 b 3 c 5 中最小的值 m2,之前的醜數 2都小於當前最大的醜數 之後的醜數 2都大於當前最大的醜數 m3 m5 def getuglynumber index if index 1 return 0 res...