問題是「合併ķ分類鏈接列表,並返回它作爲一個排序列表。」從leetcode這段代碼的時間複雜度是多少(來自leetcode)?
1.
我的解決方案是使用一個向量,以保持每個鏈表的當前位置,排序該矢量以最小值獲取節點並將其插入到合併列表的末尾。下面是代碼:
bool cmp(ListNode *a, ListNode *b) {
return a->val < b->val;
}
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
ListNode *dummy = new ListNode(-1);
ListNode *curr = dummy;
//init
vector<ListNode*> currNodes;
for(int i = 0; i < lists.size(); ++i){
if(lists[i] != NULL){
currNodes.push_back(lists[i]);
}
}
while(!currNodes.empty()){
sort(currNodes.begin(), currNodes.end(), cmp);
curr->next = currNodes[0];
curr = curr->next;
if(currNodes[0]->next != NULL){
currNodes.push_back(currNodes[0]->next);
}
currNodes.erase(currNodes.begin());
}
return dummy->next;
}
};
由於性病的時間複雜度::排序是n日誌(n)和我們(N1 + N2 ... NK)的迭代,從而我想總的時間複雜度爲O( (N1 + N2 + ... NK)KLOG(K))。但在每次迭代中,矢量currNodes
的大小可能會有所不同,所以我有點困惑。任何人都可以確認嗎?
2. 此外,我看到另一個解決方案在leetcode論壇上使用「合併排序」的思想。它每次都合併兩個鏈表。
public class Solution {
public ListNode mergeKLists(ArrayList<ListNode> lists) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if(lists.isEmpty()) return null;
if(lists.size() == 1) return lists.get(0);
int k = lists.size();
int log = (int)(Math.log(k)/Math.log(2));
log = log < Math.log(k)/Math.log(2)? log+1:log; // take ceiling
for(int i = 1; i <= log; i++){
for(int j = 0; j < lists.size(); j=j+(int)Math.pow(2,i)){
int offset = j+(int)Math.pow(2,i-1);
lists.set(j, mergeTwoLists(lists.get(j), (offset >= lists.size()? null : lists.get(offset))));
}
}
return lists.get(0);
}
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if(l1 == null) return l2;
if(l2 == null) return l1;
ListNode head = l1.val > l2.val? l2:l1;
if(head.equals(l2)){
l2 = l1;
l1 = head;
}
while(l1.next != null && l2 != null){
if(l1.next.val > l2.val){
ListNode tmp = l1.next;
l1.next = l2;
l2 = l2.next;
l1 = l1.next;
l1.next = tmp;
}
else
l1 = l1.next;
}
if(l2 != null){
l1.next = l2;
}
return head;
}
}
我想知道這個解決方案的時間複雜度是多少?由於它每次都合併兩個鏈表,所以有log(n)次迭代。但是鏈表在每次迭代之後會變長(因爲它是從兩個鏈表中合併的),如何計算每次迭代的時間複雜度並將它們疊加在一起?
先謝謝您:)