Skip to content

Commit

Permalink
added 115
Browse files Browse the repository at this point in the history
  • Loading branch information
pezy committed Feb 10, 2015
1 parent 43039e4 commit 5075945
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 0 deletions.
30 changes: 30 additions & 0 deletions 115. Merge k Sorted Lists/README.md
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.
44 changes: 44 additions & 0 deletions 115. Merge k Sorted Lists/main.cpp
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;
}

33 changes: 33 additions & 0 deletions 115. Merge k Sorted Lists/solution.h
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());
}
};

0 comments on commit 5075945

Please sign in to comment.