You are given the heads of two sorted linked lists list1
and list2
. Merge the two lists into one sorted list. The list should be made by splicing together the nodes of the first two lists. Return the head of the merged linked list.
Eg.
Input: list1 = [1,2,4], list2 = [1,3,4]
Output: [1,1,2,3,4,4]
Constraints:
- The number of nodes in both lists is in the range
[0, 50]
. -100 <= Node.val <= 100
- Both
list1
andlist2
are sorted in non-decreasing order.
********
Singly-linked lists有ListNode组成。该类包含两个属性:此节点的值val, 此节点指向的下一个节点next。
// Definition for singly-linked list.
public class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
这题需要注意两个点:
- dummy node的设计。
- 题目要求返回合并后的链表的head。假设合并链表是 1 -> 1 -> 2,需要返回1。
- 决定合并链表的第一个节点略烦。因为while循环的逻辑(比较list1当前节点与list2当前节点的值,将较小者赋给合并链表的next)需要合并链接一开始不为空。
- 最明显的做法是在while循环前比较list1和list2的head。这是有些重复的做法。所以,直接创建dummy node,方法最终返回dummy.next即可。
- 这也是链表相比ArrayList的好处:返回时可以简单的选择开始元素。
- while循环条件的设计。
- 木板原理:只要list1和list2同时还有节点,就比较。
- 比较完共同部分,哪个list还剩下节点,直接贴到合并链接结尾。
解法如下:
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if ((list1 == null) && (list2 == null)) {
return null;
}
if (list1 == null) {
return list2;
}
if (list2 == null) {
return list1;
}
ListNode dummy = new ListNode(-1);
ListNode combined = dummy;
while ((list1 != null) && (list2 != null)) {
if (list1.val < list2.val) {
combined.next = new ListNode(list1.val);
list1 = list1.next;
} else {
combined.next = new ListNode(list2.val);
list2 = list2.next;
}
combined = combined.next;
}
if (list1 != null) {
combined.next = list1;
}
else if (list2 != null) {
combined.next = list2;
}
return dummy.next;
}
}