diff --git a/115. Merge k Sorted Lists/README.md b/115. Merge k Sorted Lists/README.md new file mode 100644 index 0000000..0b29ef2 --- /dev/null +++ b/115. Merge k Sorted Lists/README.md @@ -0,0 +1,30 @@ +这一阶段的 LeetCode 有一个明显的特点,就是在增加难度的同时,还紧密联系之前的 Easy 难度的题目。 + +昨天的两道姊妹题是如此,今天的链表题依旧如此。 + +这道题,显然是 [019. Merge Two Sorted Lists](../019. Merge Two Sorted Lists) 的升级版。 + +对于想复习基础的链表操作的童鞋,我推荐看看我的[这篇总结](http://segmentfault.com/blog/pezy/1190000002490878)。 + +----- + +拿到问题,合并多个链表。而此刻,我们已经掌握了合并两个链表的方法。于是我们很自然的列出以下几种情况: + +- lists.empty() : 返回 NULL +- lists.size() == 1 : 返回该链表 +- lists.size() == 2 : 正好碰枪口,mergeTwoLists. +- lists.size() == 3 : 先合并后两个,在将其结果与第三个合并。 +- lists.size() == 4 : 先两两合并,然后再将结果合并。 +- ... + +就没必要一直列下去了吧。 + +分而治之,是非常自然而然的思路,我们如果会造枪,但要的却是炮,我们将枪捆在一起,捆的无限多,便成了炮。 + +注意,为了更方便分治,我们将原题目的接口扩展为更通用的迭代器接口。 + +然后核心的语句是: + + return mergeTwoLists(mergeKLists(beg, beg + std::distance(beg, end)/2), mergeKLists(beg + std::distance(beg, end)/2, end)); + +提交,AC,离最快差了不过 4 ms. \ No newline at end of file diff --git a/115. Merge k Sorted Lists/main.cpp b/115. Merge k Sorted Lists/main.cpp new file mode 100644 index 0000000..267a03c --- /dev/null +++ b/115. Merge k Sorted Lists/main.cpp @@ -0,0 +1,44 @@ +#include "solution.h" +#include + +using namespace std; + +ListNode *create_linkedlist(std::initializer_list lst) +{ + auto iter = lst.begin(); + ListNode *head = lst.size() ? new ListNode(*iter++) : nullptr; + for (ListNode *cur=head; iter != lst.end(); cur=cur->next) + cur->next = new ListNode(*iter++); + return head; +} + +void clear(ListNode *head) +{ + while (head) { + ListNode *del = head; + head = head->next; + delete del; + } +} + +void printList(ListNode *head) { + for (ListNode *cur = head; cur; cur = cur->next) + cout << cur->val << "->"; + cout << "\b\b " << endl; +} + +int main() +{ + Solution s; + vector vec{ + create_linkedlist({1,3,5,7,9}), + create_linkedlist({2,4,6,8,10}), + create_linkedlist({0,11,12,13,14}) + }; + ListNode *ret = s.mergeKLists(vec); + printList(ret); + clear(ret); + + return 0; +} + diff --git a/115. Merge k Sorted Lists/solution.h b/115. Merge k Sorted Lists/solution.h new file mode 100644 index 0000000..72cacce --- /dev/null +++ b/115. Merge k Sorted Lists/solution.h @@ -0,0 +1,33 @@ +#include +using std::vector; +#include + +struct ListNode { + int val; + ListNode *next; + ListNode(int x) : val(x), next(NULL) {} +}; + +class Solution { + ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) { + ListNode *head = NULL, **lastPtrRef = &head; + for (;l1 && l2; lastPtrRef = &((*lastPtrRef)->next)) { + if (l1->val <= l2->val) { *lastPtrRef = l1; l1 = l1->next; } + else { *lastPtrRef = l2; l2 = l2->next; } + } + *lastPtrRef = l1 ? l1 : l2; + return head; + } + + using vecNodeCIter = vector::const_iterator; + ListNode *mergeKLists(vecNodeCIter beg, vecNodeCIter end) { + if (beg == end) return NULL; + else if (std::distance(beg, end) == 1) return *beg; + else if (std::distance(beg, end) == 2) return mergeTwoLists(*beg, *std::next(beg)); + else return mergeTwoLists(mergeKLists(beg, beg + std::distance(beg, end)/2), mergeKLists(beg + std::distance(beg, end)/2, end)); + } +public: + ListNode *mergeKLists(vector &lists) { + return mergeKLists(lists.cbegin(), lists.cend()); + } +};