給你乙個鍊錶陣列,每個鍊錶都已經按公升序排列。
請你將所有鍊錶合併到乙個公升序鍊錶中,返回合併後的鍊錶。
示例 1:
輸入:lists = [[1,4,5],[1,3,4],[2,6]]
輸出:[1,1,2,3,4,4,5,6]
解釋:鍊錶陣列如下:
[1->4->5,
1->3->4,
2->6
]將它們合併到乙個有序鍊錶中得到。
1->1->2->3->4->4->5->6
示例 2:
輸入:lists =
輸出:示例 3:
輸入:lists =
輸出:k == lists.length
0 <= k <= 10^4
0 <= lists[i].length <= 500
-10^4 <= lists[i][j] <= 10^4
lists[i] 按 公升序 排列
lists[i].length 的總和不超過 10^4
解答一:在乙個迴圈中,依次將兩個鍊錶合併,合併後的結果放到其中乙個鍊錶,另乙個鍊錶設定為nullptr,**如下,
listnode* mergetwolist(listnode* l1, listnode*l2)if (l2 ==nullptr)
if (l1->val < l2->val)
else
}return result->next;;
}listnode* mergeklists(vector&lists)
while (lists.at(idx2) == nullptr && idx1 if (idx1 ==idx2)
//合併兩個鍊錶
result =mergetwolist(lists.at(idx1), lists.at(idx2));
lists.at(idx1) =result;
idx2--;
}return
result;
}
提交後通過,但是合併次數為n-1,修改如下
解答二:讓vector中的元素兩兩合併,合併後再遞迴呼叫,減少合併次數,分治法
vectormergesubstep(vectorlists)if (vec.size() < 2
)
return
vec;
vector
tmpvec;
int idx1 = 0, idx2 = vec.size() - 1
;
while (idx1 if (vec.size() % 2 == 1)//
奇數個,把中間的新增到vec
return
tmpvec;
}listnode* mergeklists2(vector&lists)
return result.at(0
);}
其中,兩個鍊錶合併的**跟解答一中的一樣,省略。提交後,相對於解答一,速度提高了很多。
看解答。
一:合併兩個鍊錶,解答中的效率較高,**如下:
listnode* mergetwolists(listnode *a, listnode *b)else
tail = tail->next;
}tail->next = (aptr ?aptr : bptr);
return
head.next;
}
該函式中,判斷是否為nullptr以及比較很少,在兩個鍊錶都不為空時取較小值,當其中乙個為nullptr後,直接將next指向另乙個鍊錶即可。而自己寫的合併在乙個while中多次判斷鍊錶是否為nullptr,效率較低。
二:解答中的分治使用兩個index,這樣在遞迴呼叫時不會產生中間的vector,以節約記憶體:而且求l+r的平均值時,使用的是右移操作,比除2效率高。
listnode* merge(vector &lists, int l, intr) listnode* mergeklists(vector&lists)
23 合併K個公升序鍊錶
給你乙個鍊錶陣列,每個鍊錶都已經按公升序排列。請你將所有鍊錶合併到乙個公升序鍊錶中,返回合併後的鍊錶。示例 1 輸入 lists 1,4,5 1,3,4 2,6 輸出 1,1,2,3,4,4,5,6 解釋 鍊錶陣列如下 1 4 5,1 3 4,2 6 將它們合併到乙個有序鍊錶中得到。1 1 2 3 ...
23 合併K個公升序鍊錶
題目描述 給你乙個鍊錶陣列,每個鍊錶都已經按公升序排列。請你將所有鍊錶合併到乙個公升序鍊錶中,返回合併後的鍊錶。示例 1 輸入 lists 1,4,5 1,3,4 2,6 輸出 1,1,2,3,4,4,5,6 解釋 鍊錶陣列如下 1 4 5,1 3 4,2 6 將它們合併到乙個有序鍊錶中得到。1 1...
23 合併K個公升序鍊錶
這道題,用歸併可太秀了。學習一下鍊錶歸併的寫法 遞迴,最好也要知道飛遞迴寫法 關於對鍊錶歸併遞迴解法的理解,這一篇講得好 一看就會,一寫就廢?詳解遞迴 非遞迴解法就是迭代,穿針引線,改變指標。最好設定乙個哨兵節點,操作方便。在 21.合併兩個有序鍊錶 這一題中自己寫了一遍,感覺不夠優雅,看看別人是怎...