劍指offer之醜數

2021-07-05 02:20:53 字數 2133 閱讀 2428

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

對於這個問題,最容易想的就是乙個個數進行判斷,

如:

public

static

intgetuglynumber(int index)

}i++;}}

public

static

boolean

isuglynumber(int number)

if(number == 1)else

}

index = 100

1536

678.071ms

index = 1000

51200000

2545589.285ms

儲存所有檢測過的資料,並且採用hash表

setset = new hashset();

if(index == 1)

set.add(1);

int i = 2;

int count = 1;

while(true)else

if((i % 3 == 0) && set.contains(i/3))else

if((i % 5 == 0) && set.contains(i/5))

if(count == index )

i++;

}

index = 100

1536

1745.431ms(甚至還不如第一種,hashset預設是16,所以需要不停的擴容)

index = 1000

51200000

2401278.071ms(初始指定容量為20480時,效果較明顯)

指定hashset初始容量為20480

index = 100

1536

2340.335ms

index = 1000

51200000

1875198.538ms

但是依然令人不滿意,那麼有沒有更好的方法呢?

第一種:需要對每乙個數都進行判斷,而當index很大時,判斷函式消耗了太多的無用時間

第二種:雖然利用了先前的計算結果,但是hash表的擴容操作會是乙個很耗時間的操作,儘管我們看不到;

那麼是否可以利用先前的結果,而又避免擴容呢?

假設array裡已經儲存了n個醜數(已經按大小排好序),那麼第n+1個醜數一定是前面所有醜數乘以2,乘以3,乘以5的最小值,這是一定的,因為醜數一定是醜數的乘積。其次為了保持陣列的順序,所以選擇最小值。

如果遍歷n個數,然後分別乘以2,3,5,計算最小值,將又會是o(n^2)的操作。

由於陣列排好序了,設最大值為m,那麼存在乙個位置flag2,使得array[flag2]*2大於m,而array[flag2-1]*2小於等於m,同理對於位置flag3,位置flag5也有這個性質

因此為了計算第n+1個醜數,只需要計算min

public

static

intgetuglynumber2(int index)

int ugly = new

int[index];

ugly[0] = 1;

int count = 1;

int flag2 = 0;//flag2*2大於ugly[count-1]

int flag3 = 0;//flag3*3大於ugly[count-1]

int flag5 = 0;//flag5*5大於ugly[count-1]

while(count < index)

if(ugly[flag3]*3

<= ugly[count])

if(ugly[flag5]*5

<= ugly[count])

count++;

}return ugly[index-1];

}

index = 100:

1536

196.414ms

index = 1000:

51200000

292.321ms

改變非常明顯

劍指offer 醜數

把只包含因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。分析 參考程式設計師面試金典 偽 如下 1 初始化array和佇列 q2 q3 q5 2 將1插入array 3 分別將1 2...

劍指Offer 醜數

我們把只包含因子 2 3 和 5 的數稱作醜數 ugly number 求按從小 到大的順序的第 1500 個醜數。例如 6 8都是醜數,但 14 不是,它包含因子 7。習慣上我們把 1當做第乙個醜數。解法一 逐一判斷是否是醜數,簡單但是不夠高效 數字n是數字m的因子說明m n 0。醜數的因子只有2...

劍指offer 醜數

把只包含因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。分析 為了保證時間達到要求,可以將所求得的醜數都儲存在陣列中,然後再取出。前面的醜數乘以2 3或5中的最小的乙個是下乙個醜數。...