输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。
示例1:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
限制:
0 <= 链表长度 <= 1000
1. 递归
/**
* @author LanceQ
* @version 1.0
* @time 2021/5/2 17:20
*/
public class MergeLinkedList {
public static void main(String[] args) {
ListNode l1 = new ListNode(2), l2 = new ListNode(5);
l1.next = new ListNode(7);
l1.next.next = new ListNode(9);
l2.next = new ListNode(8);
l2.next.next = new ListNode(11);
System.out.println(Merge(l1,l2));
}
private static ListNode Merge(ListNode l1, ListNode l2) {
if(l1==null){
return l2;
}
if (l2==null){
return l1;
}
if(l1.val<l2.val){
l1.next=Merge(l1.next,l2);
return l1;
}else{
l2.next=Merge(l1,l2.next);
return l2;
}
}
}
运行结果:
2->5->7->8->9->11->null
问题分析
-
假设我们有两个链表 l1,l2;
-
把头节点l1的值与头结点l2的值比较,假设A1小,则l1为头节点,否则就是l2位头结点;
-
然后把你设为头结点的指针,即假设l1.next指向下一个比较得到小的数
-
而这个小的数,可以通过递归的方式,来获取“Merge(ListNode l1, ListNode l2) ”中比较小的值。
-
如此循环往复,当有一个为空的时候,就可以把另一个直接上去了。
时间复杂度:
-
时间复杂度:O(m + n)(因为每次递归只需要比较1次,而比较最多就是m+n次,所以时间复杂度为O(m + n),其中m、n分别为两个链表的长度)
-
空间复杂度:O(m + n)(因为没有创建新的链表来暂时存储节点,都是在原来的链表的基础上,改变链表指向下一个的指向,所以,空间复杂度为O(m + n))
2. 迭代
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode();
ListNode cur = dummy;
while(l1 != null && l2 != null){
if(l1.val <= l2.val){
cur.next = l1;
l1 = l1.next;
}else{
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
cur.next = l1 != null ? l1 : l2;
return dummy.next;
}
}
-
设置dummy为哑结点,放置于新链表之前,最后返回的就是dummy.next;设置cur为当前节点从dummy开始
-
当两个链表都非空时进入循环,令新链表的下一个节点cur.next为val更小的节点,相应的链表节点后移一位
-
每次循环记得cur也要后移一位
-
如果循环结束后还有链表非空,cur指向非空链表,并返回dummy.next
复杂度分析
- 时间复杂度:O(m + n),m和n分别为两链表长度
- 空间复杂度:O(1)
参考:https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/
https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/solution/jian-zhi-offer-25-he-bing-liang-ge-pai-x-b8g0/