算法题学习---合并两个排序的链表

85 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情

题目

描述

输入两个递增的链表,单个链表的长度为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

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

示例2

输入:
{},{}
返回值:
{}

示例3

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

分析

考虑特殊情况

在进行问题分析过程前,我们先考虑一下特殊情况,那么在这道问题中,有哪些情况是特殊的呢?

不难发现,如下情况:

  • pHead1是空链表或者pHead2是空链表,那么我们只需要返回对方即可

当然两者都是空链表的情况返回对方也是可以的

考虑一般情况

由于需要按顺序排列,这里我们最先想到的就是使用两个指针分别遍历两个链表,直到两个指针中出现空指针的情况,在遍历过程中,做如下判断:

  • 如果链表1的元素小于链表2的元素,那么先链接1的元素,链表1的指针后移;
  • 否则,先链接2的元素,链表2的指针后移。

出现一个链表指针为空的情况,说明另一个链表的元素都比之前的元素大,这时只需要将剩余的元素链接到末尾即可。

代码示例

注意,这里还做了一些额外的处理:

  • pReturn:记录返回的头结点,指向较小的头结点;
  • pCur0:记录merge链表的当前位置;
  • pCur1:记录链表1的当前位置;
  • pCur2:记录链表2的当前位置。
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
  public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
        // special condition
        if (nullptr == pHead1) {
            return pHead2;
        }

        if (nullptr == pHead2) {
            return pHead1;
        }

        ListNode* pReturn = nullptr;
        ListNode* pCur0 = nullptr;
        ListNode* pCur1 = pHead1;
        ListNode* pCur2 = pHead2;

        // assign the pReturn
        if (pHead1->val <= pHead2->val) {
            pReturn = pHead1;
            pCur1 = pCur1->next;
        } else {
            pReturn = pHead2;
            pCur2 = pCur2->next;
        }
        pCur0 = pReturn;

        // traverse the two list and link them
        while(nullptr != pCur1 && nullptr != pCur2){
            if(pCur1->val <= pCur2->val){
                pCur0->next = pCur1;
                pCur1 = pCur1->next;
            }else{
                pCur0->next = pCur2;
                pCur2 = pCur2->next;
            }
            pCur0 = pCur0->next;
        }

        if(nullptr == pCur1){
            pCur0->next = pCur2;
        }else if(nullptr == pCur2){
            pCur0->next = pCur1;
        }

        return pReturn;
    }
};