LEETCODE(力扣)21. 合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

1.自解

image
时间与空间结果不错,但是逻辑可能有些复杂

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 /*该解法思路在于选定一个首结点值较小的链表,遍历该链表上的节点与另一个链表的比较节点作比较,直到找到一个本节点值
 小于比较节点,本节点下个节点值大于比较节点的节点,将比较节点的值插入到本节点后面
 简单的来说就是将一条链表插入另一条链表上
 看了标准答案后感觉该思路对链表的理解还是不够深刻*/
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
    struct ListNode *temp,*head;//head用于记录返回的首节点,temp用于插入节点时的中间变量
    temp=list1;
    head=list1;
    if(list1==NULL&&list2==NULL)return NULL;
    if(list1==NULL)
    {
        list1=list2;
        return list1;
    }else if(list2==NULL)
    {
        return list1;
    }
    if(list1->val>list2->val)/*list1必须为为首结点较小的那个(因为我们返回的head其实就是插入list2的list1)
                               不先将list1设为更小的那个就要写list1首结点大于list2首结点的判断逻辑*/
    {
        list1=list2;
        list2=temp;
        temp=list1;
        head=list1;
    }
        while(list1->next!=NULL&&list2!=NULL)//遍历到list2空或list1的最后一个节点
        {
            if(list1->val<=list2->val&&list1->next->val>list2->val)//必须找到最大的list1节点值小于list2节点值的节点
            {
                temp=list2->next;
                list2->next=list1->next;
                list1->next=list2;
                list2=temp;
                list1=list1->next;
            }
            else
            {
                list1=list1->next;
            }
        }
    if(list2!=NULL)//在list1比list2先空时连接list2剩下的节点,若list2先空则直接返回head(也就是插入了list2的list1)
    {
        list1->next=list2;
    }
    return head;
}

自解:
l1:1 3 4 5
l2:4 6 7 8
l1:1 3 4 4 5 678

2.标准答案

标准答案比较简洁,思路是将list1、list2两条链表的节点分配到一条新链表上

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
    struct ListNode  head ;
    struct ListNode *h = &head;
 if(list1 == NULL && list2 == NULL)//判断是否非空
    return NULL;
 while (list1 != NULL && list2 != NULL){//从头部依次判断两个链表的每一个值的大小
     if ( list1->val < list2->val){
     h->next = list1;
     list1 = list1->next;
     h = h->next;
     }
     else{
     h->next = list2;
     list2 = list2->next;
     h = h->next;
     }  }
 if (list1 != NULL && list2 == NULL)//其中一个非空的情况
    h->next = list1;
 if (list2 != NULL && list1 == NULL)//同理
    h->next = list2;
   return head.next;
}

标准:
l1:1 3 4 5
l2:4 6 7 8
l3:1 3 4 4 5 678

其实能发现两个自解与标准解答在合并链表上是两个不同的思路,但代码却有许多相似的地方,十分的有意思

posted @ 2025-04-24 16:51  Osen  阅读(39)  评论(0)    收藏  举报