Merge Two Sorted Lists
Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes
of the first two lists.
將兩個有序鏈表合併並返回新的鏈表。新鏈表是由原鏈表的節點鏈接組成。
分析:
維護一個新的頭指針,分別從 L1 和 L2 的頭結點開始向後比較,將值小的節點加入新鏈表,然後指針後移,另一個不變,重複此過程直到兩個鏈表合併完。
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
struct ListNode *head = NULL, *pre = NULL;
if(!l2) //l2爲空指針,直接返回l1
{
return l1;
}
if(!l1)//l2不爲空,l1爲空
{
l1 = l2;
return l1;
}
while(l1 || l2)
{
if(!l1) /* l1合併完成,l2沒完成 */
{
pre->next = l2;
pre = pre->next;
l2 = l2->next;
continue;
}
if(!l2)/* l2合併完成,l1沒有完成 */
{
pre->next = l1;
pre = pre->next;
l1 = l1->next;
continue;
}
/* l1 l2 都沒合併完*/
if(NULL == head)/*第一個節點*/
{
if(l1->val <= l2->val) /*l1小,加入新鏈表*/
{
head = pre = l1;
l1 = l1->next;
if(pre->val == l2->val)/*l1 l2 相等,都加入新鏈表*/
{
pre->next = l2;
pre = pre->next;
l2 = l2->next;
}
}
else/*l2 小,加入新鏈表*/
{
head = pre = l2;
l2 = l2->next;
}
}
else
{
if(l1->val <= l2->val) /*l1小,加入新鏈表*/
{
pre->next = l1;
l1 = l1->next;
pre = pre->next;
if(pre->val == l2->val)/*l1 l2 相等,都加入新鏈表*/
{
pre->next = l2;
pre = pre->next;
l2 = l2->next;
}
}
else/*l2 小,加入新鏈表*/
{
pre->next = l2;
pre = pre->next;
l2 = l2->next;
}
}
}
return head;
}
Merge k Sorted Lists
Merge k sorted
linked lists and return it as one sorted list. Analyze and describe its complexity.
將 k 個有序鏈表合併成一個新鏈表並返回,分析和描述複雜度。
分析:
歸併排序。對每個有序鏈表看成一個整體,然後和其他的鏈表進行歸併排序。時間複雜度爲 O(nlogn).
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
if(lists.empty()) //空
{
return NULL;
}
if(lists.size() == 1)
{
return lists[0];
}
//歸併排序
return mergeList(lists);
}
//劃分
ListNode* mergeList(vector<ListNode*>& lists){
int listsSize = lists.size();
if(1 == listsSize)
{
return lists[0];
}
vector<ListNode*> vleft(lists.begin(), (lists.begin() + (listsSize-1)/2 + 1));
vector<ListNode*> vright((lists.begin() + (listsSize-1)/2 + 1), lists.end());
ListNode *left = mergeList(vleft);//左半部分歸併排序
ListNode *right = mergeList(vright);//右半部分歸併排序
return merge2Lists(left, right);
}
//合併
ListNode* merge2Lists(ListNode* left, ListNode* right){
if(!left && !right)
{
return NULL;
}
ListNode *tempHead = new ListNode(0), *pre = tempHead; //新建頭結點
ListNode *head = left;
ListNode *plist = right;
while(head || plist)
{
if(!head) //head合併完,lists[i]沒有完成
{
pre->next = plist;
pre = pre->next;
plist = plist->next;
continue;
}
if(!plist)//lists[i]合併完,head沒有完成
{
pre->next = head;
pre = pre->next;
head = head->next;
continue;
}
if(head->val <= plist->val)//head <= lists[i]
{
pre->next = head;
pre = pre->next;
head = head->next;
if(pre->val == plist->val)//注意:此處是 pre->val, head已經指向下個節點
{
pre->next = plist;
pre = pre->next;
plist = plist->next;
}
}
else //head > lists[i]
{
pre->next = plist;
pre = pre->next;
plist = plist->next;
}
}
head = tempHead->next;
delete tempHead;
return head;
}
};