JZ25 合并两个排序的链表

283 阅读2分钟

Day24 2023/01/31

题目链接

难度:简单

题目

输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排序的。

数据范围:0≤n≤1000,1000≤节点值≤1000
要求:空间复杂度 O(1),时间复杂度O(n)

如输入{1,3,5},{2,4,6}时,合并后的链表为{1,2,3,4,5,6},所以对应的输出为{1,2,3,4,5,6},转换过程如下图所示:

或输入{-1,2,4},{1,3,4}时,合并后的链表为{-1,1,2,3,4,4},所以对应的输出为{-1,1,2,3,4,4},转换过程如下图所示:

示例、

输入:{1,3,5},{2,4,6}
返回值:{1,2,3,4,5,6}

思路


先设置一个虚拟头节点,依次比较两个链表的头节点,将节点数据较小的连接到虚拟头节点之后。直到两个链表中其中一个为空的时候,将另一个链表直接连接到虚拟头节点构成链表的尾节点上。
具体步骤:

  1. 遍历两个链表,当其中一个为空的时候退出循环。
  2. 遍历的过程中比较两个链表头节点的数据,将较小的插入到虚拟头节点所构成链表的尾部。
  3. 退出循环后将不为空的链表直接连接到虚拟头节点所构成链表的尾部。
  4. 返回真正的头节点。

算法实现-插入法


c++代码实现

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
  public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
        ListNode* pHead = new ListNode(-1); //虚拟头节点
        ListNode* cur = pHead; //新链表的尾指针
        while (pHead1 && pHead2) { //有空链表了就退出循环
            if (pHead1->val <= pHead2->val) {
                cur->next = pHead1; //将较小的节点插入
                pHead1 = pHead1->next;
            } else {
                cur->next = pHead2;
                pHead2 = pHead2->next;
            }
            cur = cur->next; //始终指向当前尾节点
        }
        cur->next = pHead1 ? pHead1 : pHead2; //将不为空的呢个链表插入的新链表尾部
        return pHead->next; //返回真正的头指针
    }
};

  • 时间复杂度 max(O(n),O(m))max(O(n), O(m)) --- 其中n和m分别为两个链表的长度
  • 空间复杂度 O(1)O(1) --- 操作的都是原有的节点,没有额外的辅助空间

总结

-该方法插入的方式类似链表创建中带虚拟头节点的头插法。