剑指offer22_合并两个排序的链表
合并两个排序的链表
输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。
数据范围
链表长度 [ 0 , 500 ] [0,500] [0,500]。
样例
输入:1->3->5 , 2->4->5输出:1->2->3->4->5->5
解决方案:二路归并
- 初始化
- 新建虚拟头结点
dummy
(保护结点),并让cur
指针指向dummy
。
- 新建虚拟头结点
- 比较与合并
- 比较
l1
和l2
当前结点的值val
:- 若
l1->val < l2->val
:- 令
cur->next
指向l1
,并将l1
后移。
- 令
- 否则:
- 令
cur->next
指向l2
,并将l2
后移。
- 令
- 若
- 移动
cur
指针到新连接的结点(cur = cur->next
)。
- 比较
- 处理剩余链表
- 当
l1
或l2
为空时,将cur->next
指向未遍历完的链表(剩余部分直接接上)。
- 当
解决方案:二路归并
- 时间复杂度:两个链表各遍历一次,总时间复杂度为 O(n)。
- 空间复杂度:仅使用常数个额外指针(
dummy
和cur
),空间复杂度为 O(1)。
/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/
class Solution {
public:ListNode* merge(ListNode* l1, ListNode* l2) {auto dummy = new ListNode(-1), cur = dummy;while(l1 && l2){if(l1->val < l2->val){cur = cur->next = l1;l1 = l1->next;}else{cur = cur->next = l2;l2 = l2->next;}}if(l1) cur->next = l1;if(l2) cur->next = l2;return dummy->next;}
};