剑指offer16_合并两个排序的链表_题解

合并两个排序的链表

题目描述

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

示例1

输入

{1,3,5},{2,4,6}

返回值

{1,2,3,4,5,6}

分析

方案一:迭代版本

引入伪头节点: 由于初始状态合并链表中无节点,因此循环第一轮时无法将节点添加到合并链表中。解决方案:初始化一个辅助节点 \(dum\) 作为合并链表的伪头节点,将各节点添加至 \(dum\) 之后。

image-20201213165646088.png

/**
时间复杂度:O(n)
空间复杂度:O(1)
**/
class Solution {
public:
    ListNode *Merge(ListNode *pHead1, ListNode *pHead2)
    {
        ListNode *dummyhead = new ListNode(-1); //虚拟头结点
        ListNode *cur = dummyhead;              //cur指向新链表的头结点

        while (pHead1 && pHead2)
        {
            // 如果l1指向的结点值小于等于l2指向的结点值,则将l1指向的结点值链接到cur的next指针
            if (pHead1->val <= pHead2->val)
            {
                cur->next = pHead1;
                pHead1 = pHead1->next;
            }
            // 否则将l2指向的结点值链接到cur的next指针
            else
            {
                cur->next = pHead2;
                pHead2 = pHead2->next;
            }
            cur = cur->next;
        }
		//合并剩余尾部
        cur->next = pHead1 ? pHead1 : pHead2;
        return dummyhead->next;
    }
};

方案二:递归版本

递归终止条件

①如果链表 \(l1\)\(l2\) 均为空,返回空结点

②如果链表 \(l1\)\(l2\) 不空,返回链表 \(l2\) 的头结点

③如果链表 \(l2\)\(l1\) 空,返回链表 \(l1\) 的头结点

递归函数

如果 \(PHead1\) 的所指节点值小于等于 \(pHead2\) 所指的结点值,那么\(PHead1\) 后续节点和 \(pHead\) 节点继续递归

/**
时间复杂度:O(n)
空间复杂度:O(n)
**/
class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
         if (!pHead1 && !pHead2) return NULL;
         if (!pHead1) return pHead2;
         if (!pHead2) return pHead1;
         //如果l1.val <= l2.val,那么头结点的值为l1.head的值,然后开始递归
         if (pHead1->val <= pHead2->val) {
             pHead1->next = Merge(pHead1->next, pHead2);
             return pHead1;
         }
         //否则,头结点的值为l2.head的值,然后开始递归
         else {
             pHead2->next = Merge(pHead1, pHead2->next);
             return pHead2;
         }
    }
};
posted @ 2020-12-13 18:22  RiverCold  阅读(43)  评论(0编辑  收藏  举报