题目描述
将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
思路
1.递归
先找出子问题,子问题可以化为:
当L1[0]小于等L2[0]时,L = L1[0] + merge(L1[1:N],L2)
否则, L = L2[0] + merge(L1,L2[1:N])
递归出口为当L1或L2为null时
Java代码
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;
}
}
算法复杂度分析
时间复杂度:O(M+N),因为每次递归调用只去掉剩下L1或L2的头结点,直到有一个链表为空,因此至多调用M+N次
空间复杂度:O(M+N),每次递归调用需要消耗栈空间,因为每次栈空间只访问一次头结点,因此至多消耗M+N
2.迭代
遍历比较L1和L2的首节点,可以先设置一个临时头结点pre,若L1小,那么可以将pre指向L1,否则pre指向L2,以此来合并。最后当终止循环时,最多剩一个链表不为空,因为L1和L2都是升序排列的,某个链表剩下的部分肯定都是大于之前合并的部分。然后再将之前合并的加上某个链表剩下的部分。
Java代码
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
//迭代求解
ListNode pHead = new ListNode(-1);//作为合并链表的头结点
ListNode pre;//合并链表的当前节点
pre = pHead;
while(l1 != null && l2 != null){
if(l1.val <= l2.val){
pre.next = l1;
//l1.next = l2;
l1 = l1.next;
}
else{
pre.next = l2;
//l2.next = l1;
l2 = l2.next;
}
pre = pre.next;
}
pre.next = l1 == null?l2:l1;
return pHead.next;
}
}
算法复杂度分析
时间复杂度:O(M+N),遍历M+N-R次,R为某链表剩下的部分长度,因此 至多为M+N
空间复杂度:O(1),只需要常数级空间来储存变量
本文介绍如何将两个升序链表合并为一个新的升序链表,提供递归和迭代两种方法,并分析了各自的算法复杂度。
684

被折叠的 条评论
为什么被折叠?



