输入两个单调递增的链表,输出两个链表合成后的链表,满足单调不减规则

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

方法一:使用递归

下面的图使用了一个例子,给出了递归的详细过程,假设pHead1有三个数,分别为1,3,5;pHead2也有三个数,分别为2,4,6。

递归压栈过程:将后面未知的部分看做一个黑盒,newhead指向排好序的最后一个元素,newhead->next指向黑盒,黑盒表示剩下的所有元素,newhead不断向后指,直到满足终止条件

出栈过程:return pHead2首先将元素6返回给newhead->next,最后一句return newhead将栈元素一步步取出,newhead和newhead->next不断向前指,最终newhead指向第一个元素1,函数结束

/*
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 *newhead=NULL;
        if(pHead1->val<pHead2->val)
        {
            newhead=pHead1;
            newhead->next=Merge(pHead1->next,pHead2);
        }
        else
        {
            newhead=pHead2;
            newhead->next=Merge(pHead1,pHead2->next);
        }
        return newhead;
    }
};

方法二:建立一个顺序容器vector<int>vec;将两个链表的值依次送入容器中,在用sort函数进行排序(从大到小),用ListNode类型的指针反向指出每一个数值

/*
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;
        if(pHead2==NULL)
            return pHead1;
        vector<int>vec;         //保存两个链表中的数值
        ListNode *first=NULL;
        while(pHead1)
        {
            vec.push_back(pHead1->val);
            pHead1=pHead1->next;
        }
        while(pHead2)
        {
            vec.push_back(pHead2->val);
            pHead2=pHead2->next;
        }
        
        //保存两个链表的元素后,对其进行排序
        //这里对vec中的元素从大到小排,因为链表从前面插入
        sort(vec.begin(),vec.end(),greater<int>());
        
         //排序后将vec中的元素插入到链表,从前面插入
        for(int i=0;i<vec.size();i++)
        {
            ListNode *newnode=new ListNode(vec[i]);
            newnode->next=first;
            first=newnode;
        }
        return first;
    }
};

方法三:设置两个指针,head一个指向排好序的链表的第一个元素(两个链表的第一个节点中小的那个),tail初始化为NULL,根据pHead1和pHead2中要比较的那两个元素的大小选择下一个要指向的元素,一个一个指向下一个元素

当链表1为空(pHead1==NULL)的时候,直接返回链表2的首地址pHead2

当链表2为空(pHead2==NULL)的时候,直接返回链表1的首地址pHead1

指针不断向后指,当链表1的内容已经为空,链表2不为空时,另tail->next指向链表2中剩下元素中第一个元素;链表1不为空,链表2为空亦然。

/*
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)    //此处不能为else,否则判断pHead1不为空之后,直接返回pHead1
            return pHead1;
        ListNode *p1=pHead1;
        ListNode *p2=pHead2;
        ListNode *head=NULL;
        ListNode *tail = NULL;
        if(p1->val < p2->val)
        {
            head = tail = p1;
            p1 = p1->next;
         }
         else
         {
             head = tail = p2;
             p2 = p2->next;
         }
         while(p1 && p2)
         {
             if (p1->val < p2->val)
             {
                 tail->next = p1;
                 tail = p1;
                 p1 = p1->next;
             }
             else
             {
                 tail->next = p2;
                 tail = p2;
                 p2 = p2->next;
             }
         }
        if (p2) tail->next = p2;
        if (p1) tail->next = p1;
        return head;
    }
};

猜你喜欢

转载自blog.csdn.net/happyjacob/article/details/80603423