剑指offer 合并两个排序的链表

1.题目

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

来源:剑指offer
链接:https://www.nowcoder.com/practice/d8b6b4358f774294a89de2a6ac4d9337?tpId=13&tqId=11169&tPage=1&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking

2.我的题解

题意简单明了,解法也很明显,就是依次比较当前的两个表头,找到较小的那一个,找到了就可以串起来,返回结果。
(1)比较时要注意一个或两个链表为空的问题,不判断空就开始比较,会段错误。
(2)第一个节点怎么选呢?写个if...else显得累赘,增加一个辅助的头结点,可以解决这个问题,要挂上去的第一个节点就成为了结果链表的第二个节点,不需要特殊处理。
(3)最好不要开辟额外的链表返回,那样空间复杂度为O(n),最优为O(1)
1->3,2->3->4->5为例。

步骤状态
0在这里插入图片描述
1在这里插入图片描述
2在这里插入图片描述
3在这里插入图片描述
4在这里插入图片描述
5在这里插入图片描述
6(有一个为空)在这里插入图片描述
/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        ListNode * head = new ListNode(0); 
        ListNode * cur=head;
        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 head->next;
    }
};

3.别人的题解

3.1 合并排序

我一时没有反应过来,这不就是合并排序吗?最令我印象深刻的合并操作是《算法》书上的模式,它吧所有情况都用if..else写到了一起,简洁明了。

class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        ListNode * head = new ListNode(0); 
        ListNode * cur=head;
        while(pHead1 || pHead2){
            if(pHead1==NULL){cur->next=pHead2;pHead2=pHead2->next;}
            else if(pHead2==NULL){cur->next=pHead1;pHead1=pHead1->next;}
            else if(pHead1->val<=pHead2->val){cur->next=pHead1;pHead1=pHead1->next;}
            else {cur->next=pHead2;pHead2=pHead2->next;}
            cur=cur->next;
        }
        
        return head->next;
    }
};

注意:

  • 虽然第1、3分支和2、4分支的操作一样,但是不能合并分支,必须要分别判断两个表头是否为空,因为第三3、4分支的判断条件用了两个表头,你不知道哪个会先为空。

3.2 递归解法

递归解法。

class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        if(pHead1==NULL)return pHead2;
        if(pHead2==NULL)return pHead1;
        ListNode * head = NULL; 
        if(pHead1->val<=pHead2->val){
            head=pHead1;
            head->next=Merge(pHead1->next,pHead2);
        }
        else{
            head=pHead2;
            head->next=Merge(pHead1,pHead2->next);
        }
        return head;
    }
};

4.总结与反思

(1)辅助的头节点使用。
(2)合并排序的Merge操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值