Merge Two Sorted Lists
update Jun 27, 2017
Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.
思路:
这道题目使用recursion比较简单,因为recursion可以很简单的做到先处理后面的nodes再链接前面的nodes,即可以不让前面的nodes丢失后面的部分,而使用iteration就会复杂一些。
Iteration 的方法可以先使用一个无意义的 dummy node 作为头指针,然后用一个curr跟踪当前新链表的最后一个node
Recursion,Python code:
class Solution(object):
def mergeTwoLists(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
return self.merge(l1, l2)
def merge(self, l1, l2):
if not l1:
return l2
if not l2:
return l1
if l1.val <= l2.val:
# 先处理后面的,再拼接前面的
l1.next = self.merge(l1.next, l2)
return l1
else:
l2.next = self.merge(l1, l2.next)
return l2
Non Recursion, Java code:
// non-recursive solution
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) return l2;
if (l2 == null) return l1;
ListNode dummy = new ListNode(0);
ListNode curr = null;
if (l1.val < l2.val) {
curr = l1;
l1 = l1.next;
} else {
curr = l2;
l2 = l2.next;
}
dummy.next = curr;
while (l1 != null || l2 != null) {
if (l1 == null) {
curr.next = l2;
break;
} else if (l2 == null) {
curr.next = l1;
break;
} else if (l2.val < l1.val) {
curr.next = l2;
curr = curr.next;
l2 = l2.next;
} else {
curr.next = l1;
curr = curr.next;
l1 = l1.next;
}
}
return dummy.next;
}
update 2017-11-21 14:44:35
补充一点关于recursion方法的思路

Java Code
// recursive solution
public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
// base case
if (l1 == null) return l2;
else if (l2 == null) return l1;
// 选择小的作为当前head,和剩余部分merge之后的head拼接
ListNode head;
if (l1.val < l2.val) {
head = l1;
l1 = l1.next;
} else {
head = l2;
l2 = l2.next;
}
head.next = mergeTwoLists(l1, l2);
return head;
}
}
时隔数月,写出来的 non-recursion 的code也精简了不少
public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0);
ListNode curr = dummy;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
curr.next = l1;
l1 = l1.next;
} else {
curr.next = l2;
l2 = l2.next;
}
curr = curr.next;
}
if (l1 == null) curr.next = l2;
if (l2 == null) curr.next = l1;
return dummy.next;
}
}
反思
使用 dummy node 时,从 curr = dummy 开始可以节省很多code,因为第一步操作的一定是改变 curr.next;
还是要提前考虑 edge case,有了通盘考虑之后写起code更加精准;
update May 3,2018 17:42
C++ Code
Non recursion
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* dummy = new ListNode(0);
ListNode* curr = dummy;
while (l1 != nullptr && l2 != nullptr) {
if (l1->val < l2->val) {
curr->next = l1;
l1 = l1->next;
curr = curr->next;
curr->next = nullptr;
} else {
curr->next = l2;
l2 = l2->next;
curr = curr->next;
curr->next = nullptr;
}
}
ListNode* last = l1 == nullptr ? l2 : l1;
curr->next = last;
return dummy->next;
}
};
Recursion
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if (l1 == nullptr || l2 == nullptr) {
return l1 == nullptr ? l2 : l1;
}
if (l1->val < l2->val) {
l1->next = mergeTwoLists(l1->next, l2);
return l1;
} else {
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
}
};