目录
题目描述
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:
输入:l1 = [], l2 = []
输出:[]
示例 3:
输入:l1 = [], l2 = [0]
输出:[0]
各种解法
1. 递归合并两个链表
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
// 终止条件是其中的一个链表是null
if(list1 == null) return list2;
if(list2 == null) return list1;
// 把小的那个值加入到结果链表中
if(list1.val < list2.val){
list1.next = mergeTwoLists(list1.next, list2);
return list1;
}else{
list2.next = mergeTwoLists(list1, list2.next);
return list2;
}
}
}
解题思路
- 递归解法,首先不要太关注细节,只要注重函数的功能就可以。该函数的功能就是能够合并两个有序链表。那么就把大问题转化为小问题。
- 确定终止条件,一条链表为null,结果就是另一条链表
- 然后对第一个节点进行处理,根据节点大小,以小的节点连接后面子问题的结果。
2. 迭代合并两个链表
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
// 头结点之前的虚节点,为了回来能找到头结点
ListNode hair = new ListNode(-1);
ListNode pre = hair;
while(list1 != null && list2 != null){
if(list1.val < list2.val){
pre.next = list1;
list1 = list1.next;
}else{
pre.next = list2;
list2 = list2.next;
}
pre = pre.next;
}
// 合并后面还剩的部分
pre.next = list1 == null ? list2 : list1;
return hair.next;
}
}
解题思路
- 对于链表的题目,头结点很可能是不确定的,所以这时候用一个虚拟节点就可以起到很好的连接作用,最终肯定是hair.next
- 每次把两条链表中较小值的节点连接到结果链表上面
- 如果一条链表为空了,那么就可以直接把另一条链表的剩余部分接到结果链表上了。
变形题
1. 合并两个有序链表并且没有重复值,考虑去重
1.1 递归去重合并
解题思路
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
//单个链表中有重复数字,直接跳到最后一个
while(list1.next!=null&&list1.val==list1.next.val){
list1=list1.next;
}
while(list2.next!=null&&list2.val==list2.next.val){
list2=list2.next;
}
//list1与list2有相同元素
if(list1.val==list2.val){
if(list2.next!=null){
list2=list2.next;
}else{
return list1;
}
}
//以下就是官方递归解
if(list1==null){
return list2;
}
if(list2==null){
return list1;
}
if(list1.val<lis