劍指Offer面試題34題:醜數(Ugly Number)(while循環裏面的三個小問題)

語言:C/C++語言

IDE:    Mac/Xcode 

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

分析:所謂一個數m是另一個數n的因子,是指n%m==0。根據醜數的定義,醜數能被2,3,5整除,也就是一個數能連續的被2整除,或者連續的被3整除,或者連續的被5整除,或者能被2,3,5的某種組合整除,例如(2*2*3*3*3*5)這種也可以。總結:包括2,3,5的因子,可能不包括2但包括3,肯能不包括3但包括5。就是不斷的除2,3,5,如果最後的結果爲1,那麼則爲醜數。

1.給某個數,判別這個數是否爲醜數。

bool isUgly(int number)
{
      if(number<=0)return false;
      while(number%2==0)number/=2;
      while(number%3==0)number/=3;
      while(number%5==0)number/=5;
      return (number==1)?true:false;
}

2.暴力找第1500個醜數。

   分析:找第1500個醜數作爲函數的輸入參數,那麼從第一個醜數1開始找,不斷遞增,直到找到第1500個結束循環,循環條件爲第1500個,最終輸出返回這個第1500的醜數int。

則原型函數爲: int GetUglyNumber(int index);

下面爲劍指offer裏面的實現。

int GetUglyNumber(int index)
{
     if(index<=0)return 0;
     int number=0,nth=0;
     while(nth<index)
     {
         number++;
         if(isUgly(number))nth++;
     }
     return number;
}
但這裏面有三個小問題:(這三個問題大家有想過嗎?)

①.爲什麼 nth從0開始???

②.爲什麼number從0開始???

③.在while循環裏面number++在 if判斷前面???而不是下面這樣???

(也就是number++在while中的位置)

while(nth<index)
{      
   if(isUgly(number))nth++;
   number++;
}


好,我慢慢解釋。
答:在編程裏面,數組的索引均是從0開始的,而不是從1開始的,所以大家都習慣以0開始。在這個題中第1500個醜數,則是nth=1499則終止循環。若是從1開始,則就是第1500個醜數。
nth=0;
while(nth<index).....
或者
nth=1;
while(nth<=index).....
這兩個while的判斷條件差了一個等號,這是第一個問題的答案。


其實第2問題和第3問題是一個問題。
那先假設程序如下:
nth=0,number=0;
while(nth<index)
{
    if(isUgly(number))nth++
    number++;
}
在第0次循環中,number爲0不是醜數,nth爲0,number自加變爲1。
在第1次循環中,number爲1是醜數,nth自加爲1,number自加變爲2。
在第2次循環中,number爲2是醜數,nth自加爲2,number自加變爲3。
。。。。
在最後一次循環中(nth=1499),number爲xxx恰好是醜數,nth自加爲1500,然後number自加1。
再次循環而nth不滿足,則跳出循環,那麼此時的number值是xxx+1 ,而不是xxx。所以關鍵在於最後這個number++;找到了第1500個醜數後,number再自加1,則跳出循環。這是最關鍵的!!!
又有人說:number從1開始行嗎?
我的回答則是,那就是上面的分析中少了第0次循環而已,直接從第1次循環開始。最終還是會 number值爲xxx+1  。
那麼下面會對嗎????
number=1;
while(nth<index)
{
    number++
    if(isUgly(number))nth++
}
這樣也是不對的,因爲這是number從2開始判斷的,則第一個醜數本身是1,而現在是2就錯誤了。
總結:
這是我的分析,看來控制number的起點和number++在if前後是有區別的,並不是隨意放置,這是我們需要注意的重點,學習精髓,注重細節,否則得到的結果是不正確的。
而nth的起點與while裏的判斷條件相關。

    
此算法缺點是時間效率不高,太慢,一旦求第15000個醜數,估計得算半天。


3.明天待發




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章