21. 合并两个有序链表

问题描述

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

示例:

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/merge-two-sorted-lists

解法1 (C语言)

递归

l1的值比l2小时,l1即作为父节点,l1->next指向除去l1节点的l1'l2合并后的链表。

l1->next = mergeTwoLists(l1->next, l2)

//以l1 = [1,2,4], l2 = [1,3,4]为例
List1: 1 -> 2 -> 4
List2: 1 -> 3 -> 4
// -----第一次递归-----
1 = 1, List2(1)->next = mergeTwoList(l1, l2->next)
    l1:1 -> 2 -> 4
    l2: 3 -> 4
    1 < 3,List1(1)->next = mergeTwoList(l1->next, l2)
// -----第二次递归-----
        l1: 2 -> 4
        l2: 3 -> 4
        2 < 3, List1(2)->next = mTL(l1->next, l2)
// -----第三次递归-----
            l1: 4
            l2: 3 -> 4
            4 > 3, List2(3)->next = mTL(l1, l2->next)
// -----第四次递归-----
                l1: 4
                l2: 4
                4 = 4, List2(4)->next = mTL(l1, l2->next)
// -----第五次递归-----
                    l1: 4
                    l2: NULL
                    return l1;
                        
                        4
                    4 -> 4
                3 -> 4 -> 4
            2 -> 3 -> 4 -> 4
        1 -> 2 -> 3 -> 4 -> 4
    1 -> 1 -> 2 -> 3 -> 4 -> 4
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
    if(l1 == NULL)
    {
        return l2;
    }
       
    if(l2 == NULL)
    {
        return l1;
    }

    if(l1->val < l2->val)
    {
        l1->next = mergeTwoLists(l1->next, l2);
        return l1;
    }
    else
    {
        l2->next = mergeTwoLists(l1, l2->next);
        return l2;
    }
}

执行用时:4 ms, 在所有 C 提交中击败了91.62%的用户

内存消耗:6.2 MB, 在所有 C 提交中击败了5.03%的用户

解法2 (C语言)

迭代

声明一个头结点head = {0, NULL},声明一个指针cur用于遍历两个链表。

//以l1 = [1,2,4], l2 = [1,3,4]为例。
// -----第一次循环-----
l1->val == l2->val; // 1 = 1, 两个结点值相等
cur->next = l1; //头结点head的元素next(head.next,也是cur->next)指向l1
cur = cur->next; // 指针cur移到cur->next,即现在的l1
l1 = l1->next; // 指针l1移到下个元素
cur->next = l2; // 由于两结点值相等,cur的next直接指向l2
cur = cur->next; // cur移到移到cur->next,即现在的l2
l2 = l2->next; // 指针l2移到下个元素
// -----第二次循环-----
l1->val < l2->val // 2 < 3,l1指向的结点小于l2指向的结点

{
    cur->next = l1;
    cur = cur->next;
    l1 = l1->next;
    continue; // 与上面代码相似,不解释了,continue进入下一个循环
}
// -----第n个循环-----
//当两个链表长度不同时,若其中一个链表已经合并完全,则将另一个链表剩下的内容接在后面即可
if (l1 == NULL)
{
    cur->next = l2;
}

以下是完整代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
    struct ListNode head = {0, NULL};
    struct ListNode* cur = &head;
    while(l1 != NULL && l2 != NULL)
    {
        if (l1->val < l2->val)
        {
            cur->next = l1;
            cur = cur->next;
            l1 = l1->next;
            continue;
        }
        if(l1->val > l2->val)
        {
            cur->next = l2;
            cur = cur->next;
            l2 = l2->next;
            continue;
        }
        cur->next = l1;
        cur = cur->next;
        l1 = l1->next;
        cur->next = l2;
        cur = cur->next;
        l2 = l2->next;
    }
    if (l1 == NULL)
    {
        cur->next = l2;
    }
    if (l2 == NULL)
    {
        cur->next = l1;
    }
    return head.next;
}

执行用时:4 ms, 在所有 C 提交中击败了91.62%的用户

内存消耗:6 MB, 在所有 C 提交中击败了17.79%的用户

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值