题目
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4] 输出:[1,1,2,3,4,4]示例 2:
输入:l1 = [], l2 = [] 输出:[]示例 3:
输入:l1 = [], l2 = [0] 输出:[0]
分析
迭代法
我们使用一个虚拟头节点(dummy node)。这个节点不存储实际数据,只是为了方便操作,它的 next 指针将指向合并后的链表的头节点。
逐步比较两个链表的当前节点,将较小的节点连接到 tail 后面,并移动相应的链表指针。当一个链表遍历完后,直接将另一个链表的剩余部分连接到新链表的末尾。
时间复杂度:O(),
和
分别为两个链表的长度
空间复杂度:O(1)
class Solution {
public:
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
// 创建一个虚拟头节点
ListNode dummy;
ListNode* tail = &dummy;
// 比较两个链表的节点,按顺序连接到新链表
while (list1 && list2) {
if (list1->val < list2->val) {
tail->next = list1;
list1 = list1->next;
} else {
tail->next = list2;
list2 = list2->next;
}
tail = tail->next;
}
// 连接剩余的节点
if (list1) {
tail->next = list1;
} else {
tail->next = list2;
}
// 返回合并后的链表
return dummy.next;
}
};
递归法
每次递归调用返回合并后的链表的头节点。通过递归调用栈,逐层返回合并后的链表,最终返回完整的合并链表。
时间复杂度:O(),
和
分别为两个链表的长度
空间复杂度:O()
class Solution {
public:
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
// 递归终止条件
if (!list1) return list2;
if (!list2) return list1;
// 递归合并
if (list1->val < list2->val) {
list1->next = mergeTwoLists(list1->next, list2);
return list1;
} else {
list2->next = mergeTwoLists(list1, list2->next);
return list2;
}
}
};
知识充电
链表
节点定义
struct ListNode {
int val;
ListNode* next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode* next) : val(x), next(next) {}
};
初始化
// 创建链表节点
ListNode* node1 = new ListNode(1);
ListNode* node2 = new ListNode(2);
ListNode* node3 = new ListNode(3);
// 连接节点形成链表: 1 -> 2 -> 3
node1->next = node2;
node2->next = node3;
// node1是链表的头节点
ListNode* head = node1;
遍历链表
void printList(ListNode* head) {
ListNode* current = head;
while (current != nullptr) {
std::cout << current->val << " ";
current = current->next;
}
std::cout << std::endl;
}
插入节点
void insertAtEnd(ListNode*& head, int value) { //在链表的末尾插入一个新节点
ListNode* newNode = new ListNode(value);
if (!head) {
head = newNode;
return;
}
ListNode* current = head;
while (current->next != nullptr) {
current = current->next;
}
current->next = newNode;
}
删除节点
void deleteNode(ListNode*& head, int value) { //删除链表中第一个值为value的节点
if (!head) return;
if (head->val == value) {
ListNode* temp = head;
head = head->next;
delete temp;
return;
}
ListNode* current = head;
while (current->next && current->next->val != value) {
current = current->next;
}
if (current->next) {
ListNode* temp = current->next;
current->next = current->next->next;
delete temp;
}
}