leetcode——合併K個升序連結串列
阿新 • • 發佈:2021-01-20
目錄
題目:
給定一個連結串列陣列,每個連結串列都已經按升序排列。請你將所有連結串列合併到一個升序連結串列中,返回合併後的連結串列。
(https://leetcode-cn.com/problems/merge-k-sorted-lists/)
示例:
輸入: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
提示:
- 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
方案一:暴力解法
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* mergeKLists(vector<ListNode*>& lists) { ListNode* head = nullptr; ListNode* cur = nullptr; while(true) { int index = -1; for (int i = 0; i < lists.size(); i++) { if (lists[i] == nullptr) { continue; } if (index < 0 || lists[index]->val > lists[i]->val) { index = i; } } if (index < 0) { return head; } if (head == nullptr) { head = cur = lists[index]; }else { cur->next = lists[index]; cur = cur->next; } lists[index] = lists[index]->next; } return head; } };
時間複雜度
空間複雜度
方案二:順序合併
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { private: /* 合併兩個陣列,時間複雜度O(n),空間複雜度O(1) */ ListNode* mergeTwoList(ListNode* l1, ListNode* l2) { if (!l1 || !l2) return !l1 ? l2 : l1; ListNode head, *cur = &head; while (l1 && l2) { if (l1->val < l2->val) { cur->next = l1; l1 = l1->next; } else { cur->next = l2; l2 = l2->next; } cur = cur->next; } cur->next = l1 ? l1 : l2; return head.next; } public: ListNode* mergeKLists(vector<ListNode*>& lists) { ListNode* head = nullptr; ListNode* cur = nullptr; for (int i = 0; i < lists.size(); i++) { head = mergeTwoList(head, lists[i]); } return head; } };
時間複雜度:
空間複雜度:
方案三:歸併
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
private:
/*
合併兩個陣列,時間複雜度O(n),空間複雜度O(1)
*/
ListNode* mergeTwoList(ListNode* l1, ListNode* l2) {
if (!l1 || !l2) return !l1 ? l2 : l1;
ListNode head, *cur = &head;
while (l1 && l2) {
if (l1->val < l2->val) {
cur->next = l1;
l1 = l1->next;
} else {
cur->next = l2;
l2 = l2->next;
}
cur = cur->next;
}
cur->next = l1 ? l1 : l2;
return head.next;
}
ListNode* merge(vector<ListNode*>& lists, int l, int r) {
if (l == r) return lists[l];
if (l > r) return nullptr;
int mid = (l + r) >> 1;
return mergeTwoList(merge(lists, l, mid), merge(lists, mid + 1, r));
}
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
return merge(lists, 0, lists.size() - 1);
}
};
時間複雜度
空間複雜度
方案四:優先佇列
https://blog.csdn.net/weixin_36888577/article/details/79937886優先佇列相關知識
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
struct Status {
int val;
ListNode* ptr;
bool operator < (const Status &rhs) const {
return rhs.val < val;
}
};
priority_queue <Status> q;
ListNode* mergeKLists(vector<ListNode*>& lists) {
for (auto node : lists) {
if (node != nullptr) {
q.push({node->val, node});
}
}
ListNode head, *cur = &head;
while(!q.empty()) {
Status s = q.top();
q.pop();
cur->next = s.ptr;
cur = cur->next;
if (s.ptr->next) {
q.push({s.ptr->next->val, s.ptr->next});
}
}
return head.next;
}
};
時間複雜度
空間複雜度