刷题:牛客JZ25 合并两个排序的链表

106 阅读1分钟

网址: www.nowcoder.com/practice/d8…

描述

输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排序的。

数据范围: 0 \le n \le 10000≤n≤1000,-1000 \le 节点值 \le 1000−1000≤节点值≤1000
要求:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)

如输入{1,3,5},{2,4,6}时,合并后的链表为{1,2,3,4,5,6},所以对应的输出为{1,2,3,4,5,6},转换过程如下图所示:

image.png

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==nullptr)   //特殊情况,存在空链表
            return pHead2;
         if(pHead2==nullptr)
            return pHead1;
        ListNode* flag1;
        ListNode* flag2;
        
        //flag1始终指向比flag2小的结点
        if(pHead1->val > pHead2->val)
        {
            flag1=pHead2;
            flag2=pHead1;
        }
        else{
            flag1=pHead1;
            flag2=pHead2;
        }
        ListNode* ans=flag1;
        
        while(true)
        {
            if(flag1->next == nullptr)   //小的那个结点后面为空,合并要结束了
            {
                flag1->next=flag2;
                break;
            }
            if(flag2->val<flag1->next->val)   //flag2的值小于flag1的next结点的值
            {
                //使falg1的next指向flag2,完成一次拼接
                //然后交换flag1和flag2的指向,使flag1始终指向小的那个结点
                ListNode* temp=flag2;  
                flag2=flag1->next;   
                flag1->next=temp;
                flag1=flag1->next;
            }
            else{
                flag1=flag1->next;   //flag1的next结点的值比flag2的值小,则链接next这个结点
            }
        }
        return ans;
    }
};

总结:

一直有两个链表,他们的头结点分别为flag1和flag2,且满足flag1始终指向值更小的那个结点,然后判断flag1应该指向flag1的后续结点还是flag2结点。