leetcode -- 21. 合并两个有序链表

Source

在这里插入图片描述

📑1. 题目

将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例1:
在这里插入图片描述

输入: l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例 2:

输入: l1 = [], l2 = []
输出:[]

示例3:

输入: l1 = [], l2 = [0]
输出:[0]

提示:

  • 两个链表的节点数目范围是 [0, 50]
  • -100 <= Node.val <= 100
  • l1 和 l2 均按非递减顺序排列

🛶2. 解法- 头插到新链表

🐬2.1 思路

题目给我们的链表是升序的,最简单直接的思路就是将这两个链表尾插升序排列到一个新链表。

tips:

  1. 这里我们需要考虑到题目给的两个链表是否为空;
  2. 尾插时,也需判断我们的新链表是否为空;
  3. 最后需检查两个链表是否遍历完毕,如果未遍历完毕,则将剩余的元素直接尾插到新链表。

🐬2.1 代码实现

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
    
      
    if(list1 == NULL)
        return list2;
    if(list2 == NULL)
        return list1;
    struct ListNode*newhead = NULL,*tail = NULL;
    while(list1&&list2)
    {
    
      
        if(list1->val <list2->val)
        {
    
      
            if(tail == NULL)
            {
    
      
                newhead = tail =list1;
            }
            else
            {
    
      
            	//尾插
                tail->next = list1;
                tail = tail->next;
            }
            list1 = list1->next;

        }
        else
        {
    
      
            if(tail == NULL)
            {
    
      
                newhead = tail = list2;
            }
            else
            {
    
      
            	//尾插
                tail->next = list2;
                tail = tail->next;
            }
            list2 = list2->next;
        }
    }
    if(list1&&tail)
    {
    
      
        tail->next = list1;
        tail = tail->next;
    }
    if(list2&&tail)
    {
    
      
        tail->next = list2;
        tail = tail->next;
    }
    return newhead;
}

⛵3. 解法优化 - 带哨兵位

🐋3.1 思路

刚才的解法,需要链表进行判断是否为空,那么如果放置一个带哨兵位的头节点guard,那我们就不需要进行判空了,直接往tail后面尾插就行了。

tips:

  1. 这里不能直接返回guard,而是要返回guard的下一个节点,因为guard并未存储任何有效数据,只负责在这里 “站哨”
  2. 因为这里的哨兵位是我们向内存申请的空间,使用完毕之后还需要进行释放。

🐋3.2 代码实现

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
    
      
    struct ListNode*guard = NULL;
    struct ListNode*tail = NULL;
    //哨兵位
    guard = tail = (struct ListNode*)malloc(sizeof(struct ListNode));
    tail->next = NULL;
    while(list1 && list2)
    {
    
      
        if(list1->val < list2->val)
        {
    
      
            tail->next = list1;
            tail = tail->next;
            list1 = list1->next;
        }
        else
        {
    
      
            tail->next = list2;
            tail = tail->next;
            list2 = list2->next;   
        }
    }
    if(list1)
        tail->next = list1;
    if(list2)
        tail->next = list2;

    struct ListNode*head = guard->next;
    free(guard);
    return head;
}

🚤4. 题目链接

leetcode——21. 合并两个有序链表