forked from pezy/LeetCode
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
107 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#include "solution.h" | ||
#include <iostream> | ||
|
||
using namespace std; | ||
|
||
ListNode *create_linkedlist(std::initializer_list<int> 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<ListNode *> 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; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#include <vector> | ||
using std::vector; | ||
#include <cstddef> | ||
|
||
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<ListNode *>::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<ListNode *> &lists) { | ||
return mergeKLists(lists.cbegin(), lists.cend()); | ||
} | ||
}; |