力扣解題思路 醜數系列 糾錯記錄

2021-10-23 22:26:47 字數 3982 閱讀 7877

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

首先從醜數的定義我們知道,乙個醜數的因子只有2,3,5,那麼醜數p = 2 ^ x * 3 ^ y * 5 ^ z,換句話說乙個醜數一定由另乙個醜數乘以2或者乘以3或者乘以5得到,那麼我們從1開始乘以2,3,5,就得到2,3,5三個醜數,在從這三個醜數出發乘以2,3,5就得到4,6,10,6,9,15,10,15,25九個醜數,我們發現這種方法得到的醜數是重複且無序的,不符合要求。

那麼我們可以維護三個佇列:

(1)醜數陣列: 1

乘以2的佇列:2

乘以3的佇列:3

乘以5的佇列:5

選擇三個佇列頭最小的數2加入醜數陣列,同時將該最小的數乘以2,3,5放入三個佇列;

(2)醜數陣列:1,2

乘以2的佇列:4

乘以3的佇列:3,6

乘以5的佇列:5,10

選擇三個佇列頭最小的數3加入醜數陣列,同時將該最小的數乘以2,3,5放入三個佇列;

(3)醜數陣列:1,2,3

乘以2的佇列:4,6

乘以3的佇列:6,9

乘以5的佇列:5,10,15

選擇三個佇列頭里最小的數4加入醜數陣列,同時將該最小的數乘以2,3,5放入三個佇列;

(4)醜數陣列:1,2,3,4

乘以2的佇列:6,8

乘以3的佇列:6,9,12

乘以5的佇列:5,10,15,20

選擇三個佇列頭里最小的數5加入醜數陣列,同時將該最小的數乘以2,3,5放入三個佇列;

(5)醜數陣列:1,2,3,4,5

乘以2的佇列:6,8,10

乘以3的佇列:6,9,12,15

乘以5的佇列:10,15,20,25

選擇三個佇列頭里最小的數6加入醜數陣列,但我們發現,有兩個佇列頭都為6,所以我們彈出兩個佇列頭,同時將12,18,30放入三個佇列;(詳細可以參考這裡哦┏ (゜ω゜)=☞)

我們可以看出,每個佇列中的醜數說有序的,且隊頭是最小的,那麼我們每次從三個隊頭中取乙個最小的不就行了嗎。那我們是否真的需要構建這三個佇列呢,我覺得並不需要,我們只需要每次儲存並更新三個隊頭即可,每次使用完哪個隊頭就更新哪個隊頭(乘相應的2,3或5),完整**如下:

public

intgetuglynumber_solution

(int n)

return dp[n -1]

;}

接下來看我第二次做的錯誤答案:

public

intnthuglynumber

(int n)

return dp[n-1]

;}

錯誤原因已經標記出來了,題目要求每個數的因子只包含2,3,5而不是含有2,3,5!!並且也不可以用用else if,會導致出現重複元素!

所以應該用dp陣列來儲存上次遺留下的最小值,在它的基礎上進行操作:

public

intnthuglynumber

(int n)

return dp[n-1]

;}

注意指標都初始化為0噢~

思路:編寫一段程式來查詢第 n 個超級醜數。超級醜數是指其所有質因數都是長度為 k 的質數列表 primes 中的正整數。

輸入: n =

12, primes =[2

,7,13

,19]輸出:

32 解釋: 給定長度為 4 的質數列表 primes =[2

,7,13

,19],前 12 個超級醜數序列為:[1,

2,4,

7,8,

13,14,

16,19,

26,28,

32] 。

public

intnthsuperuglynumber

(int n,

int[

] primes)

for(

int j=

0;jdp[i]

= min;

}return dp[n -1]

;}

還可以用小頂堆,不過一定要記得去重!!並且注意要使用long不然中間有的比較大的數會溢位。這種方法效率很低。

public

intnthsuperuglynumber

(int n,

int[

] primes)

res=queue.

poll()

;while

(!queue.

isempty()

&&res==queue.

peek()

) queue.

poll()

;//去重

}return

(int

)res;

}

思路:

比較基礎的方式是使用堆:

public list

>

ksmallestpairs

(int

nums1,

int[

] nums2,

int k)

// });

priorityqueue<

int[

]> maxheap =

newpriorityqueue

<

int[

]>

((o1,o2)

->);

for(

int i=

0;imaxheap.

add(tmp);if

(maxheap.

size()

> k)}}

list

> res =

newarraylist

<

>()

;while

(!maxheap.

isempty()

)return res;

}public

intgetsum

(int

o)

另一種方法和之前幾個題目思想很像,用乙個陣列來記錄num1中每個元素在nums2中走了多遠就可以,每次迴圈都是nums1和nums2加起來最小的nums1往前走一步:

public list

>

ksmallestpairs

(int

nums1,

int[

] nums2,

int k)

list

> res =

newarraylist

<

>()

;if(nums1.length ==

0|| nums2.length ==0)

return res;

int[

] steps =

newint

[nums1.length]

;for

(int i=

0;ilist

list =

newarraylist

<

>()

; list.

add(nums1[minstepindex]);

list.

add(nums2[steps[minstepindex]])

; res.

add(list)

; steps[minstepindex]++;

}return res;

}

力扣解題思路 32 最長有效括號 糾錯記錄

思路 給定乙個只包含 和 的字串,找出最長的包含有效括號的子串的長度。輸入 輸出 2 解釋 最長有效括號子串為 輸入 輸出 4 解釋 最長有效括號子串為 這一題和22.括號生成類似,首先想到的是用棧來解決,先看一下我的錯誤 int count 0 stack stack newstack for i...

力扣解題思路 14 最長公共字首 糾錯記錄

思路 編寫乙個函式來查詢字串陣列中的最長公共字首。如果不存在公共字首,返回空字串 輸入 flower flow flight 輸出 fl 我首先想到的就是先取第乙個字串作為基準,然後再建立乙個整數陣列 長度和第乙個字串一樣長 然後用其他幾個字串和他相比較 相同的字元則在對應位置加1 後來一想發現不僅...

力扣解題思路 402 移掉K位數字 糾錯記錄

思路 這一題寫出來還算順利,不過主要得益於我看了題目的標籤,不然我可能不會採用棧 o 我首先觀察題目所給的例子,然後在草稿紙上模擬一下整個過程,具體是這樣的 遇到比棧頂更大的元素就直接出棧,若比棧頂小則說明此時棧頂是棧中最大的元素,在k大於0的情況下棧頂出棧,知道當前元素滿足入棧條件 stack s...