編寫乙個程式,找出第 n 個醜數。
醜數就是只包含質因數 2, 3, 5 的正整數。
1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 個醜數。
1 是醜數。
n 不超過1690。
暴力解法,建立乙個動態陣列儲存已經找到的醜數,數字從1開始每次加1,判斷是否能被2,3,5整除,除數是否在陣列中,滿足則將其加入陣列,直到陣列大小為n,結果在n接近1300時超時;
小頂堆解法,建立乙個小頂堆儲存已經找到的醜數,這裡為了複習堆的操作,我用的動態陣列,且手擼一遍小頂堆堆的插入和刪除操作,每次將堆頂元素乘以2,3,5,並將其插入小頂堆,然後刪除堆頂,時間複雜度為o(nlogn),空間複雜度為o(n);
class solution
heaparray = new arraylist<>();
heaparray.add(1l);
count = 0;
long root = 1l;
while(count != n-1)
return root.intvalue();
}public long upholdheap(long num)
if (!heaparray.contains(num2))
if (!heaparray.contains(num3))
// 刪除堆頂,將堆最後乙個元素放到堆頂,且從上往下調整
heaparray.set(0, heaparray.get(heaparray.size() - 1));
heaparray.remove(heaparray.size() - 1);
downshif(0);
return heaparray.get(0);
}// 從下往上調整順序
public void upshif(int child)
// 滿足左子節點且小於父節點,與父親交換資料
if (child%2 != 0 && heaparray.get(child) < heaparray.get(child/2) )
// 滿足右子節點且小於父節點,與父親交換資料
if (child%2 == 0 && heaparray.get(child) < heaparray.get(child/2 - 1))
}// 從上往下調整,最後無法調整則刪除此節點
public void downshif(int root) else if (rchild > heaparray.size() - 1) else else
}// 若比父親小則交換
if (heaparray.get(minchild) < heaparray.get(root))
}}
這裡還有需要優化的地方,比如已經找到了n個節點,則可以返回最大的那個節點,但是並不知道是否是第n個待插入節點即是最大,小頂堆中的所有葉子節點需要遍歷一遍查詢最大節點才是要求的那個數; leetcode 263 醜數(醜數II)
給了我們乙個醜數的概念,真是為了考驗我們什麼手段都能使出來。首先說一下第乙個題目,判斷乙個數是不是醜數,就是不斷地去除5 除3 除2就行了,當然除之前看看餘數是不是0,否則的話說明已經不能被這三個數整除了,直接結束 public boolean isugly int num return flag ...
超級醜數 用堆查詢解決
利用堆排序很容易進行查詢 質數又稱素數。乙個大於1的自然數,除了1和它自身外,不能被其他自然數整除的數叫做質數 否則稱為合數。質因數 素因數或質因子 在數論裡是指能整除給定正整數的質數。除了1以外,兩個沒有其他共同質因子的正整數稱為互質。因為1沒有質因子,1與任何正整數 包括1本身 都是互質 把只包...
大頂堆小頂堆
堆通常是乙個可以被看做一棵完全二叉樹的陣列物件 如果對一棵有n個結點的完全二叉樹的結點按層序編號 從第1層到第 1層,每層從左到右 則對任一結點i 1 i n 有 1 如果i 1,則結點i無雙親,是二叉樹的根 如果i 1,則其雙親是結點。2 如果2i n,則結點i為葉子結點,無左孩子 否則,其左孩子...