第一种方法:双指针迭代

时间复杂度:o(n)

空间复杂度:o(1)

class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
        ListNode* phead = new ListNode(0); //用于生成新链表的头结点(phead->next),val为0
        ListNode* cur = phead;
        //特殊情况处理
        if (pHead1 == nullptr)
            return pHead2;
        if (pHead2 == nullptr)
            return pHead1;

        while (pHead1 && pHead2) {
            if (pHead1->val < pHead2->val) {
                cur->next = pHead1;
                pHead1 = pHead1->next;
            } else {
                cur->next = pHead2;
                pHead2 = pHead2->next;
            }
            cur = cur->next;
        }
        //哪个链表还有剩,直接连在后面
        if (pHead1)
            cur->next = pHead1;
        if (pHead2)
            cur->next = pHead2;
        //返回合并后的链表的头结点
        return phead->next;
    }
};
class Solution {
  public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
        ListNode* phead; //设置一个节点作为合并后新链表的头结点
        //特殊情况处理
        if (pHead1 == nullptr)
            return pHead2;
        if (pHead2 == nullptr)
            return pHead1;
        //为新链表的头结点赋值
        if (pHead1->val < pHead2->val) {
            phead = pHead1;
            pHead1 = pHead1->next;
        } else {
            phead = pHead2;
            pHead2 = pHead2->next;
        }
        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;
        }
        //哪个链表还有剩,直接连在后面
        if (pHead1)
            cur->next = pHead1;
        if (pHead2)
            cur->next = pHead2;
        //返回合并后的链表的头结点
        return phead;
    }
};

写法一相比写法二省略了一次头结点的赋值。

第一种方法:双指针递归

不符合题目要求,提供出来开阔视野

时间复杂度:o(n)

空间复杂度:o(n)

  • 终止条件: 当一个链表已经因为递归到了末尾,另一个链表剩余部分一定都大于前面的,因此我们可以将另一个链表剩余部分拼在结果后面,结束递归。
  • 返回值: 每次返回拼接好的较大部分的子链表。
  • 本级任务: 每级不断进入下一个较小的值后的链表部分与另一个链表剩余部分,再将本次的节点接在后面较大值拼好的结果前面。

具体做法:

  • step 1:每次比较两个链表当前节点的值,然后取较小值的链表指针往后,另一个不变,两段子链表作为新的链表送入递归中。
  • step 2:递归回来的结果我们要加在当前较小值的节点后面,相当于不断在较小值后面添加节点。
  • step 3:递归的终止是两个链表有一个为空。

把问题拆解为,当前节点和更新后的两个链表进行合并

class Solution {
  public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
        //特殊情况处理
        if (pHead1 == nullptr)
            return pHead2;
        if (pHead2 == nullptr)
            return pHead1;
        //递归
        if (pHead1->val < pHead2->val) {
            pHead1->next = Merge(pHead1->next, pHead2);
            return pHead1;
        } else {
            pHead2->next = Merge(pHead1, pHead2->next);
            return pHead2;
        }
    }
};