剑指Offer_面试题17_合并两个有序链表

来源:互联网 发布:校园网络应急演练情况 编辑:程序博客网 时间:2024/05/16 15:05

题目描述

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

分析:这道题有点类似于面试题4_替换空格中的扩展题目:两个有序数组合并。大体思路上是一致的,代码很类似,分别遍历两个链表,将小的结点链接到新链表表尾。后期处理有点区别就是,合并数组在循环结束后,需要用while把剩余的一个数组中的元素一次加入新数组。而本题只需要用if判断哪个链表不空然后把剩下的直接链接到新链表即可,这是链表不同于顺序表的地方,存储方式不同。

/*struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {}};*/class Solution {public:    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)    {        if(!pHead1 || !pHead2)            return !pHead1 ? pHead2 : pHead1;        ListNode *head = NULL;        ListNode *p = NULL;        ListNode *p1 = pHead1;        ListNode *p2 = pHead2;        //确定头元素        if(pHead1->val < pHead2->val)        {            head = pHead1;            p1 = p1->next;        }        else        {            head = pHead2;            p2 = p2->next;        }        p = head;    //新链表的指针                while(p1 && p2)        {            if(p1->val < p2->val)            {                p->next = p1;                p1 = p1->next;            }            else{                p->next = p2;                p2 = p2->next;            }             p = p->next;        }        //这里跟合并数组不一样,数组用while        if(p1 != NULL)         {            p->next = p1;        }        else            p->next = p2;        return head;    }};
用递归思想来解决问题会很容易,因为每加入一个结点,剩下的又相当于执行一次合并操作,注意终止条件。简洁递归:
/*struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {}};*/class Solution {public:    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)    {        if(pHead1 == NULL)            return pHead2;        else if(pHead2 == NULL)            return pHead1;                ListNode *mergeHead = NULL;        if(pHead1->val < pHead2->val)        {            mergeHead = pHead1;            mergeHead->next = Merge(pHead1->next, pHead2);        }        else{            mergeHead = pHead2;            mergeHead->next = Merge(pHead1, pHead2->next);        }        return mergeHead;    }};