合并两个有序链表
1.题目描述
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例
2.基础解法
2.1 解法思路
分别让两个指针指向l1和l2链表,开始比较指针指向的数值
如果l1小,则将l1指向的值并入最终链表,l1指向下一位
2.2 一些小问题
2.2.1 链表的创建与返回
(1) 因为链表需要不停的连接到尾部,因此需要两个指针分别是head和tail
先让他们都指向空值,然后初始化,最后往tail后链接节点,返回head。例如:
// 先让他们都指向空值
ListNode tail = null, head = null;
'''
'''
// 然后初始化
if(head == null)
head = tail = new ListNode(value1);
// 最后往tail后链接节点
tail.next = new ListNode(value1);
tail = tail.next;
// 返回head
return head;
但是上面这种做法再合并链表时比较麻烦,需要判断两次head:
if (value1 <= value2) {
if(head == null)
head = tail = new ListNode(value1);
else{
tail.next = new ListNode(value1);
tail = tail.next;
}
l1 = l1.next;
}
else {
if(head == null)
head = tail = new ListNode(value2);
else {
tail.next = new ListNode(value2);
tail = tail.next;
}
l2 = l2.next;
}
因此,可以使用比较简单的方法,更改初始化方法,最后返回head.next即可
(2) 优化后的创建列表方法
// 直接初始化
ListNode head = new ListNode(0);
ListNode tail = head;
// 往tail后链接节点
tail.next = new ListNode(value1);
tail = tail.next;
// 返回head.next
return head.next;
因此可以得到比较简单的表达:
while (l1 != null && l2 != null) {
int value1 = l1.val;
int value2 = l2.val;
if (value1 <= value2) {
tail.next = l1;
tail = tail.next;
l1 = l1.next;
}
else {
tail.next = l2;
tail = tail.next;
l2 = l2.next;
}
}
2.2.2 边界条件的处理
(1)当初始一个链表为空时
当初始一个链表为空时,需要进行判断,如果l1为空,直接返回l2
if (l1 == null)
return l2;
if (l2 == null)
return l1;
(2) 当合并链表时有一个链表合并完后
当合并链表时有一个链表合并完后,例如当l1合并完,则直接将l2加入tail
if (l1 == null)
tail.next = l2;
else
tail.next = l1;
2.3代码
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode head = new ListNode(0);
ListNode tail = head;
if (l1 == null)
return l2;
if (l2 == null)
return l1;
while (l1 != null && l2 != null) {
int value1 = l1.val;
int value2 = l2.val;
if (value1 <= value2) {
tail.next = new ListNode(value1);
// 或者tail.next = l1;
tail = tail.next;
l1 = l1.next;
}
else {
tail.next = new ListNode(value2);
tail = tail.next;
l2 = l2.next;
}
}
if (l1 == null)
tail.next = l2;
else
tail.next = l1;
return head.next;
}
}
3. 递归解决
3.1 思路
递归地定义两个链表里的 merge 操作(忽略边界情况,比如空链表等):
3.2 算法
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
} else if (l2 == null) {
return l1;
} else if (l1.val < l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}