题解 | #合并k个已排序的链表#
合并k个已排序的链表
https://www.nowcoder.com/practice/65cfde9e5b9b4cf2b6bafa5f3ef33fa6
// https://www.nowcoder.com/practice/65cfde9e5b9b4cf2b6bafa5f3ef33fa6 /* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ #include <vector> class List { ListNode vHead; public: List& operator=(const List&) = default; List(ListNode* p) : vHead(0) { vHead.next = p; } List() : List(nullptr) {} // 返回链表头 ListNode* GetHead() const { return vHead.next; } bool IsEmpty() const { return vHead.next == nullptr; } int Front() const { return vHead.next->val; } // 将 x 插入到链表头,返回 x -> next ListNode* PushFront(ListNode* x) { ListNode* tmp = x->next; x->next = vHead.next; vHead.next = x; return tmp; } // 弹出第一个元素 ListNode* PopFront() { if (IsEmpty()) return nullptr; auto ret = vHead.next; vHead.next = ret->next; ret->next = nullptr; return ret; } // 反转链表 void Reverse() { List tmp; while (vHead.next != nullptr) vHead.next = tmp.PushFront(vHead.next); *this = tmp; } // 将从第 n 个节点开始的子链表分割,并返回 List Split(int n) { ListNode* p1 = &vHead; for (int i = 0; i < n - 1; ++i) { if (p1 == nullptr) return {}; // 什么都不分割 p1 = p1->next; } List ret(p1->next); p1->next = nullptr; return ret; } // 将分割并返回最后 n 个节点。如果链表少于 n 个节点,那么返回 null List SplitR(int n) { if (n <= 0) return nullptr; // 非法情况 ListNode* p2 = vHead.next; for (int i = 1; i < n && p2 != nullptr; ++i) { // 将快指针移至第 n 个元素处 p2 = p2->next; } if (p2 == nullptr) return nullptr; // 少于 n 个元素 if (p2->next == nullptr) return vHead.next; // 正好 n 个元素 ListNode* p1 = vHead.next; p2 = p2->next->next; // 保证 p1 到 p2 之间有 n 个元素(不算 p1, p2) while (p2 != nullptr) { p1 = p1->next; p2 = p2->next; } p2 = p1->next; // 返回值 p1->next = nullptr; return p2; } // 将两个链表合并 void Merge(const List& p) { auto tail = &vHead; while (tail->next != nullptr) { tail = tail->next; } tail->next = p.GetHead(); } void oddEvenReorder() { List l1, l2; while (!IsEmpty()) { l1.PushFront(this->PopFront()); if (!IsEmpty()) l2.PushFront(this->PopFront()); } while (!l2.IsEmpty()) this->PushFront(l2.PopFront()); while (!l1.IsEmpty()) this->PushFront(l1.PopFront()); } // 将两个有序链表合并。首先保证这两个链表是有序的 void MergeInorder(List& l2) { if (l2.IsEmpty()) return; if (IsEmpty()) { *this = l2; return; } auto& l1 = *this; List ret; while (!l1.IsEmpty() && !l2.IsEmpty()) { if (l1.Front() < l2.Front()) ret.PushFront(l1.PopFront()); else ret.PushFront(l2.PopFront()); } while (!l1.IsEmpty()) ret.PushFront(l1.PopFront()); while (!l2.IsEmpty()) ret.PushFront(l2.PopFront()); ret.Reverse(); *this = ret; } // 均分链表,返回后半段 List Div() { if (vHead.next == nullptr) return {}; // 无元素 if (vHead.next->next == nullptr) return {}; // 1 个元素 ListNode* p1 = &vHead; ListNode* p2 = p1; while (p2 != nullptr && p2->next != nullptr) { p1 = p1->next; // p1 每次走一步 p2 = p2->next->next; // p2 每次走两步 } ListNode* ret = p1->next; p1->next = nullptr; return ret; } // 归并排序 void Sort() { if (IsEmpty()) return; if (vHead.next->next == nullptr) return; // 1 个元素 List& l1 = *this; List l2 = l1.Div(); l1.Sort(); l2.Sort(); l1.MergeInorder(l2); } // 是否是回文串 bool IsPail() { if (IsEmpty()) return true; if (vHead.next->next == nullptr) return true; // 1 个元素 List& l1 = *this; List l2 = l1.Div(); l2.Reverse(); auto p1 = l1.GetHead(); auto p2 = l2.GetHead(); bool isPail = true; while (p1 != nullptr && p2 != nullptr) { if (!isPail) break; if (p1->val != p2->val) isPail = false; p1 = p1->next; p2 = p2->next; } l2.Reverse(); l1.Merge(l2); if (!isPail) return false; return true; } ListNode* EntryOfLoop() const { if (vHead.next == nullptr) return nullptr; auto p1 = vHead.next; auto p2 = p1; bool hasCycle = false; while (p2 != nullptr && p2->next != nullptr) { p1 = p1->next; // p1 每次走一步 p2 = p2->next->next; // p2 每次走两步 if (p1 == p2) { // 相遇则有环 hasCycle = true; break; } } if (!hasCycle) return nullptr; // 找环的入口 p2 = vHead.next; while (p1 != p2) { p1 = p1->next; p2 = p2->next; } return p1; } ListNode* FindFirstCommonNode(const List& l2) const { const List& l1 = *this; auto p1 = l1.vHead.next, p2 = l2.vHead.next; while (p1 != p2) { if (p1 == nullptr) p1 = l2.vHead.next; else p1 = p1->next; if (p2 == nullptr) p2 = l1.vHead.next; else p2 = p2->next; } return p1; } // 删除 p 的下一个节点 ListNode* RemoveNextOf(ListNode* p) { auto ret = p->next; p->next = p->next->next; return ret; } void Unique() { if (vHead.next == nullptr) return; // 0 个元素 if (vHead.next->next == nullptr) return; // 1 个元素 ListNode* p = vHead.next; while (p->next != nullptr) { if (p->val == p->next->val) { RemoveNextOf(p); } else { p = p->next; } } } void deleteDuplicates() { if (vHead.next == nullptr) return; // 0 个元素 if (vHead.next->next == nullptr) return; // 1 个元素 ListNode* pre = &vHead; ListNode* p = vHead.next; while (p != nullptr && p->next != nullptr) { if (p->val != p->next->val) { // 若不相等 pre = p; p = p->next; } else { // 相等 // 删除与 p 相同的所有元素 while (p->next != nullptr && p->val == p->next->val) RemoveNextOf(p); RemoveNextOf(pre); // 注意删除 p p = pre->next; // 更新 p } } } // 合并多个有序链表 static List mergeListsInorder(vector<List>& lists) { List ret; // 删除空链表 for (int i = 0; i < lists.size(); ++i) { if (lists[i].IsEmpty()) { // 将当前链表交换到容器尾部 swap(lists[i], lists.back()); lists.pop_back(); --i; } } while (!lists.empty()) { int ans = 0; // 选择最小的节点放入 for (int i = 0; i < lists.size(); ++i) { if (lists[i].Front() < lists[ans].Front()) { ans = i; } } ret.PushFront(lists[ans].PopFront()); if (lists[ans].IsEmpty()) { swap(lists[ans], lists.back()); lists.pop_back(); } } ret.Reverse(); return ret; } }; class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param lists ListNode类vector * @return ListNode类 */ ListNode* mergeKLists(vector<ListNode*>& lists) { // write code here vector<List> tmp; for (auto p : lists) tmp.push_back(p); return List::mergeListsInorder(tmp).GetHead(); } };