每天一道Code 23 合併K個公升序鍊錶

2021-10-23 17:26:17 字數 2867 閱讀 8933

**思路:

最傻的方法應該就是設乙個ans,每次用第i個鍊錶和ans合併,並儲存在ans中,每個鍊錶都合併一次。

時間複雜度:設最長鍊錶長度為n,所以第一次合併,ans也就是第乙個鍊錶,長度n

nn,第二次合併,ans長度為2n2n

2n,依次合併,第i個鍊錶合併完ans長度為inin

in,每次合併都是遍歷一次,求和為∑i=

1ki⋅

n=k(

k−1)

2n\sum_^i·n=\cfracn

i=1∑k​

i⋅n=

2k(k

−1)​

n 故時間複雜度o(k

2n)o(k^2n)

o(k2n)

**就不寫了,無非就是迴圈。

分治思想

乙個乙個往最終結果上合併時間太長,於是兩兩合併,鍊錶數量就會從k

kk到k

2\cfrac

2k​,再到k

4\cfrac

4k​…直到最後合併為乙個。

時間複雜度:第一次合併時,有k

2\cfrac

2k​組鍊錶參與兩兩合併,合併後每組長度為2n2n

2n,因此第一次合併時間k22

n=kn

\cfrac2n=kn

2k​2n=

kn。第二次合併有k

4\cfrac

4k​組鍊錶參與合併,合併後每組長度4n4n

4n,第二次合併時間k44

n=kn

\cfrac4n=kn

4k​4n=

kn…事實上,還有落單的鍊錶,但是因為**中可以直接返回也就意味著落單鏈表不會過多影響時間。

求和得:

∑ i=

1⌈lo

g2k⌉

k2i2

in=k

⋅n⋅l

og2k

\sum_^\cfrac2^in=k·n·log_2k

i=1∑⌈l

og2​

k⌉​2

ik​2

in=k

⋅n⋅l

og2​

k即時間複雜度o(k

⋅n⋅l

og2k

)o(k·n·log_2k)

o(k⋅n⋅

log2

​k)

優先佇列

也可以使用優先佇列實現,只不過有幾個注意的點。

優先佇列的時間複雜度:優先佇列中元素個數不超過k個,則插入和刪除元素的時間複雜度為o(l

ogk)

o(log k)

o(logk

),每個節點都會進隊出隊一次,因此總時間複雜度o(k

⋅n⋅l

ogk)

o(k·n·logk)

o(k⋅n⋅

logk

)注意事項:

優先佇列是由堆實現的,內部自含排序,因此優先佇列的元素不能使用題中的節點指標,因為沒法通過該指標實現排序。

優先佇列預設是由大根堆實現的。

盡量不要用迭代器去訪問vector,因為本來vector中存放的就是指標,再使用iterator訪問,雙指標,混亂無比,反正我是沒繞過來彎。可以使用vector本身的性質也就是v[i]這種方式或者通過auto自動設定變數型別來遍歷。

**:

/**

* definition for singly-linked list.

* struct listnode

* listnode(int x) : val(x), next(nullptr) {}

* listnode(int x, listnode *next) : val(x), next(next) {}

* };

*/class solution

else

head=head->next;

} head->next=

(first?first:second)

;return dummy->next;

} listnode*

merge

(vector

>

& lists,

int l,

int r)

listnode*

mergeklists

(vector

>

& lists)

};

/**

* definition for singly-linked list.

* struct listnode

* listnode(int x) : val(x), next(nullptr) {}

* listnode(int x, listnode *next) : val(x), next(next) {}

* };

*/class solution

bool operator <

(const point &a)

const};

listnode*

mergeklists

(vector

>

& lists)

while

(!q.

empty()

)return deummy->next;}}

;

每天一道演算法題4 查詢最小的k個元素

題目 輸入 n個整數,輸出其中最小的 k個。例如輸入 1,2,3,4,5,6,7和 8這 8個數字,則最小的 4個數字為 1,2,3和 4。分析 這道題最簡單的思路莫過於把輸入的 n個整數排序,這樣排在最前面的 k個數就是最小的 k個數。只是這種思路的時間複雜度為 o nlog n 我們試著尋找更快...

每天一道Code 814 二叉樹剪枝

思路 第一反應應該就是遞迴解決。當前節點需要刪除的條件有三個 當前節點值為0 左子樹沒有1 右子樹沒有1 definition for a binary tree node.struct treenode treenode int x val x left nullptr right nullptr...

每天一道演算法題 鍊錶中倒數第k個結點

題目描述 輸入乙個鍊錶,輸出該鍊錶中倒數第k個結點。測試用例 1,對應輸出應該為 分析 1.兩個指標,先讓第乙個指標和第二個指標都指向頭結點,然後再讓第乙個指正走 k 1 步,到達第k個節點。然後兩個指標同時往後移動,當第乙個結點到達末尾的時候,第二個結點所在位置就是倒數第k個節點了 listnod...