首页 > 其他分享 >21_合并两个有序链表

21_合并两个有序链表

时间:2024-09-29 09:01:31浏览次数:1  
标签:ListNode 21 list1 next 链表 有序 list2 节点

21_合并两个有序链表

【问题描述】

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

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

示例二:
输入:l1 = [], l2 = []
输出:[]

示例三:
输入:l1 = [], l2 = [0]
输出:[0]

提示:

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

【算法设计思想】

  1. 在解决本题时,我们需要创建一个新的带有头结点的单链表(操作方便)用来做返回的结果,然后我们初始化一个指针指向这个名为prehead的结点用来便于我们进行相关的操作。
  2. 接下来,我们初始化p1和p2两个指针变量来分别指向我们要进行操作的两个单链表,当不为空时,我们判断其所指向元素的大小,加入到我们的结果中。
  3. 最后,我们看下是否有剩余,然后直接把剩余的所有元素加入到我们的结果链表中即可。

注意:在这里我们要返回prehead -> next,因为人家题目里给的是不带头结点的单链表。

【算法描述】

C++:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        // 创建一个虚拟头节点,以便简化操作
        ListNode* prehead = new ListNode(-1);
        
        // prev指针用于遍历和构建合并后的链表
        ListNode* prev = prehead;
        
        // 两个指针分别指向两个链表的起始位置
        ListNode* p1 = list1;
        ListNode* p2 = list2;
        
        // 遍历两个链表,直到其中一个链表结束
        while (p1 != nullptr && p2 != nullptr) {
            // 比较 p1 和 p2 所指节点的值,将较小的节点连接到结果链表
            if (p1->val > p2->val) {
                prev->next = p2;  // p2 较小,连接到结果链表
                p2 = p2->next;    // p2 向后移动
            } else {
                prev->next = p1;  // p1 较小或相等,连接到结果链表
                p1 = p1->next;    // p1 向后移动
            }
            prev = prev->next;  // prev 向后移动,继续构建结果链表
        }
        
        // 如果链表1还有剩余的节点,直接连接
        if (p1 != nullptr) {
            prev->next = p1;
        }
        
        // 如果链表2还有剩余的节点,直接连接
        if (p2 != nullptr) {
            prev->next = p2;
        }
        
        // 返回合并后的链表头节点(跳过虚拟头节点)
        return prehead->next;
    }
};

Java:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    /**
     * 合并两个升序链表,并返回合并后的新链表。
     * @param list1 第一个有序链表
     * @param list2 第二个有序链表
     * @return 合并后的有序链表
     */
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        // 创建一个虚拟头节点,用于简化链表的连接操作
        ListNode prehead = new ListNode(-1);
        
        // prev 指针用于构建合并后的链表
        ListNode prev = prehead;
        
        // 遍历两个链表,直到其中一个链表遍历结束
        while (list1 != null && list2 != null) {
            // 如果 list1 的当前节点的值大于等于 list2 的当前节点
            if (list1.val >= list2.val) {
                // 将 list2 的当前节点连接到结果链表
                prev.next = list2;
                // 移动 list2 指针到下一个节点
                list2 = list2.next;
            } else {
                // 否则,将 list1 的当前节点连接到结果链表
                prev.next = list1;
                // 移动 list1 指针到下一个节点
                list1 = list1.next;
            }
            // 移动 prev 指针到下一个位置,准备连接下一个节点
            prev = prev.next;
        }
        
        // 如果 list1 还有剩余节点,直接将其连接到结果链表
        if (list1 != null) {
            prev.next = list1;
        }
        
        // 如果 list2 还有剩余节点,直接将其连接到结果链表
        if (list2 != null) {
            prev.next = list2;
        }

        // 返回合并后的链表头节点,跳过虚拟头节点
        return prehead.next;
    }
}

Python:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next

class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        # 创建一个虚拟头节点,用于简化链表的合并操作
        prehead = ListNode(-1)
        # prev 指针用于构建合并后的链表,初始指向虚拟头节点
        prev = prehead
        
        # 遍历两个链表,直到其中一个链表遍历完毕
        while list1 is not None and list2 is not None:
            # 比较 list1 和 list2 当前节点的值
            if list1.val >= list2.val:
                # 如果 list2 的值较小,将 list2 的节点连接到合并链表
                prev.next = list2
                # 移动 list2 指针到下一个节点
                list2 = list2.next
            else:
                # 如果 list1 的值较小,将 list1 的节点连接到合并链表
                prev.next = list1
                # 移动 list1 指针到下一个节点
                list1 = list1.next
            
            # 移动 prev 指针到下一个位置,准备连接下一个节点
            prev = prev.next
        
        # 如果 list1 链表还有剩余节点,直接将其连接到合并链表
        if list1 is not None:
            prev.next = list1
        
        # 如果 list2 链表还有剩余节点,直接将其连接到合并链表
        if list2 is not None:
            prev.next = list2
        
        # 返回合并后的链表,跳过虚拟头节点
        return prehead.next

C:

/**
 * Definition for singly-linked list.
 * 结构体定义一个单链表节点
 * struct ListNode {
 *     int val; // 节点值
 *     struct ListNode *next; // 指向下一个节点的指针
 * };
 */

// 合并两个已排序的链表
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
    // 创建一个伪头节点,方便处理合并后的链表
    struct ListNode* prehead = (struct ListNode*)malloc(sizeof(struct ListNode));
    prehead -> next = NULL; // 初始化伪头节点的next为NULL
    
    // prev用于追踪合并后链表的当前最后一个节点
    struct ListNode* prev = prehead;
    
    // 当两个链表都不为空时进行循环
    while(list1 != NULL && list2 != NULL){
        // 如果list2的当前节点值小于等于list1的当前节点值,则将list2的当前节点插入到结果链表中
        if(list1 -> val >= list2 -> val){
            prev -> next = list2;
            // 移动list2的头指针到下一个节点
            list2 = list2 -> next;
        }
        // 否则,将list1的当前节点插入到结果链表中
        else{
            prev -> next = list1;
            // 移动list1的头指针到下一个节点
            list1 = list1 -> next;
        }
        
        // 更新prev指向当前链表的最后一个节点
        prev = prev -> next;
    }
    
    // 如果list1还有剩余节点,则直接连接到结果链表之后
    if(list1 != NULL){
        prev -> next = list1;
    }
    // 如果list2还有剩余节点,则直接连接到结果链表之后
    if(list2 != NULL){
        prev -> next = list2;
    }

    // 返回合并后的链表(从prehead的下一个节点开始)
    return prehead -> next;
}

标签:ListNode,21,list1,next,链表,有序,list2,节点
From: https://www.cnblogs.com/zeta186012/p/18438826

相关文章

  • 链表高频题
    链表高频题160.相交链表#include<vector>#include<iostream>#include<algorithm>structListNode{intval;ListNode*next;ListNode(intx):val(x),next(NULL){}};classSolution{public:ListNode*getIntersectionNode(Li......
  • 代码随想录算法训练营Day03-链表 | LC203移除链表元素、LC707设计链表、LC206反转链表
    目录前言LeetCode203.移除链表元素思路完整代码LeetCode707.设计链表思路完整代码LeetCode206.反转链表思路完整代码今日总结前言拖延症犯了,哈哈,拖了一天LeetCode203.移除链表元素给你一个链表的头节点head和一个整数val,请你删除链表中所有满足Node.val......
  • 20221409童诗嘉《密码系统设计》第四周
    20221409童诗嘉《密码系统设计》第四周AI对学习内容的总结要求让kimi阅读学习内容并进行总结,教材内容可以使用微信读书或者云班课电子教材HeadFirstC嗨翻C语言第五章:Structs,Unions,andBitfields:Rollingyourownstructures1、编译过程与多源文件管理:编译流程:......
  • 代码随想录算法训练营第三天|203.移除链表元素,707.设计链表,206.反转链表
    203.移除链表元素文章链接:https://programmercarl.com/0203.移除链表元素.html#算法公开课视频讲解:https://www.bilibili.com/video/BV18B4y1s7R9题目出处:https://leetcode.cn/problems/remove-linked-list-elements/卡哥在这里讲解了为什么要使用虚拟头节点,以及使用和不使......
  • 面试题 02.07. 链表相交
    明天回家喽,最近在学习的瓶颈期,感觉学的东西好难,有厌学的心理,但是我相信过了这段煎熬的时期,就好了。classSolution{public:ListNode*getIntersectionNode(ListNode*headA,ListNode*headB){intna=0,nb=0;ListNode*tempA=headA;L......
  • 链表分割 1.2版本
    现有一链表的头指针ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。思路:大致可以分为两个区域来存储数据:区域一存储小于36的节点,区域二存储大于36的节点.可以将这两个区域视为两个链表......
  • 算法训练营第三天| 203.移除链表元素、707.设计链表、206.反转链表
    203.移除链表元素状态:完成个人思路:首先令head符合条件,之后判断这个head是否为空,空的话返回空节点;非空的话继续进行。令pre=head;cur=head->next,只要cur非空,就判断cur的值的情况,如果需要删除,就改变pre->next和cur;如果不需要删除就继续检查下一个。看完讲解视频之后的想法:我......
  • 代码随想录算法训练营第三天 | 熟悉链表
    链表的存储方式数组是在内存中是连续分布的,但是链表在内存中可不是连续分布的。链表是通过指针域的指针链接在内存中各个节点。所以链表中的节点在内存中不是连续分布的,而是散乱分布在内存中的某地址上,分配机制取决于操作系统的内存管理。链表的定义template<typenameT>......
  • 《DNK210使用指南 -CanMV版 V1.0》第二十七章 摄像头图像调整实验
    第二十七章摄像头图像调整实验1)实验平台:正点原子DNK210开发板2)章节摘自【正点原子】DNK210使用指南-CanMV版V1.03)购买链接:https://detail.tmall.com/item.htm?&id=7828013987504)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/k210/ATK-DNK210.html5......
  • 2133: 练4.4 牛吃牧草
    ****题目描述:有一个牧场,牧场上的牧草每天都在匀速生长,这片牧场可供15头牛吃20天,或可供20头牛吃10天,那么,这片牧场每天新生的草量可供几头牛吃11天?****输出:一个自然数,表示每天新生的草量可供几头牛吃1天。****样例输出:10include<bits/stdc++.h>usingnamespacestd;intm......