西安市做网站的浏览器老是出现站长工具
题目
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例
示例 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;}
}