合并两个排序的链表(递归&非递归)

题目描述

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

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

(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(nullptr == pHead1 && nullptr == pHead2)
            return nullptr;
        ListNode * pHead = new ListNode(0);
        ListNode * cur = pHead ;
        while(true)
        {
            if(nullptr == pHead1)
            {
                cur->next =pHead2;
                break;
            }
            else if(nullptr == pHead2)
            {
                cur->next = pHead1;
                break; 
            }
             if(pHead1->val > pHead2->val)
                swap(pHead1, pHead2);
            cur->next = pHead1;
            cur = cur->next;
            pHead1 = pHead1->next;
    }
         return pHead->next;
    }
};

点击练习合并两个排序的链表

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要将两个非递减有序链表合并成一个非递增有序链表,可以采用归并排序的思想。 具体来说,可以比较两个链表的头结点的值,将值较大的头结点作为合并后新链表的头结点,然后递归地将两个链表剩余部分合并起来。 最终链表即为非递增有序链表。 ### 回答2: 题目描述: 给定两个非递减的有序链表,要求将它们合并为一个非递增的有序链表。 解题思路: 由于原链表已经是非递减的有序链表了,因此,我们可以采用归并排序的思想进行合并。具体来说,我们可以维护三个指针,分别指向待合并两个链表和新链表的头节点。此时,我们比较两个链表的当前节点,将较大节点插入新链表的头部,然后将当前节点向后移动一位,直到有一个链表的当前节点为空。然后,将剩余的链表继续插入新链表的头部,最后返回新链表的头节点即可。 代码实现: 下面是具体实现,其中p1和p2分别指向待合并两个链表,p指向新链表的头节点,cur指向新链表当前节点: ```python def mergeList(p1: ListNode, p2: ListNode) -> ListNode: if not p1: return p2 if not p2: return p1 cur = ListNode(None) p = cur while p1 and p2: if p1.val >= p2.val: p.next = p1 p1 = p1.next else: p.next = p2 p2 = p2.next p = p.next if p1: p.next = p1 if p2: p.next = p2 return cur.next ``` 时间复杂度: 我们需要遍历两个链表,时间复杂度为O(n+m),其中n和m分别为两个链表的长度。 ### 回答3: 合并非递减的有序链表可以采用双指针的方法,通过比较两个链表中较小的元素添加到新的链表中。但是本题要求合并为非递增的有序链表,即新链表中元素要按照非递减的顺序排列。 一个简单的方法是在双指针比较大小时,如果有相等的元素,则让两个指针都向后移动,这样相等的元素就可以并列排在新链表中。另外,由于新链表是非递增的,插入元素时需要从链表头开始比较,因此可以使用头插法来避免反转链表。 具体步骤如下: 1.定义一个新链表,初始化为一个空链表。 2.利用双指针依次比较两个链表的元素,将较小的元素添加到新链表中,并让指针后移。 3.如果遇到相等的元素,让两个指针都向后移动。 4.重复步骤2-3直到一个链表遍历完毕。 5.将未遍历完的链表中的元素添加到新链表末尾。 6.返回新链表的头节点。 代码实现如下: ``` ListNode* merge(ListNode* l1, ListNode* l2) { ListNode *dummy = new ListNode(0); while (l1 && l2) { if (l1->val <= l2->val) { dummy->next = l1; l1 = l1->next; } else { dummy->next = l2; l2 = l2->next; } dummy = dummy->next; } if (l1) dummy->next = l1; if (l2) dummy->next = l2; ListNode *ans = reverseList(dummy->next); //反转链表 return ans; } ListNode* reverseList(ListNode* head) { ListNode *prev = nullptr, *cur = head; while (cur) { ListNode *temp = cur->next; cur->next = prev; prev = cur; cur = temp; } return prev; } ``` 其中,函数`reverseList`用于反转链表,这是因为我们在添加节点时使用了头插法,导致链表是反着的,需要反转一下。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值