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

21. 合并两个有序链表

时间:2023-10-20 22:33:38浏览次数:41  
标签:ListNode 21 val nullptr list1 next 链表 有序 list2

1.题目介绍

2.题解

一定注意题目给的两个链表可能为空,需要提前进行判断

2.1 初版(就是链表最基本的插入操作)

/**
 * 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 *p1 = nullptr, *p2 = nullptr, *temp = nullptr, *pre = nullptr;
        bool flag = false;
        if (list1 == nullptr) return list2;
        if (list2 == nullptr) return list1;
        if (list1->val <= list2->val) {
            p1 = list1;
            p2 = list2;
        }
        else {
            p1 = list2;
            p2 = list1;
            flag = true;
        }
        while (p1 != nullptr && p2 != nullptr) {
            while (p1->val <= p2->val) {
                pre = p1;
                p1 = p1->next;
                if (p1 == nullptr) {
                    pre->next = p2;
                    if (!flag) return list1; else return list2;
                }
            }
            p1 = pre;
            temp = p2->next;
            p2->next = p1->next;
            p1->next = p2;
            p2 = temp;
        }
        if (!flag) return list1; else return list2;
    }
};

2.2 优化

虚拟头结点

在上面的程序中,进行了一次大小判断决定是以list1还是list2为头结点进行,为此还要设置标志位flag为后面return判断提供依据。在最后某个链表遍历结束后进行的判断也过于分散不利于阅读。
但是只要使用一个虚拟头结点便可解决这些问题:

    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        if (list1 == nullptr) return list2;
        if (list2 == nullptr) return list1;

        /* 虚拟头结点 */
        ListNode dummy(0);
        ListNode* current = &dummy;

        while (list1 != nullptr && list2 != nullptr) {
            if (list1->val <= list2->val) {
                current->next = list1;
                list1 = list1->next;
            } else {
                current->next = list2;
                list2 = list2->next;
            }
            current = current->next;
        }

        if (list1 != nullptr) {
            current->next = list1;
        } else {
            current->next = list2;
        }

        return dummy.next;
    }

完整程序实例

#include <iostream>

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) {
        if (list1 == nullptr) return list2;
        if (list2 == nullptr) return list1;

        /* 虚拟头结点 */
        ListNode dummy(0);
        ListNode* current = &dummy;

        while (list1 != nullptr && list2 != nullptr) {
            if (list1->val <= list2->val) {
                current->next = list1;
                list1 = list1->next;
            } else {
                current->next = list2;
                list2 = list2->next;
            }
            current = current->next;
        }

        if (list1 != nullptr) {
            current->next = list1;
        } else {
            current->next = list2;
        }

        return dummy.next;
    }

    void Print_LinkList(ListNode* l) {
        using namespace std;
        cout << "该链表为:";
        while (l != nullptr) {
            cout << l->val << ' ';
            l = l->next;
        }
        cout << endl;
    }
};

int main() {
    Solution solution;
    ListNode* head1 = new ListNode(1);
    head1->next = new ListNode(2);
    head1->next->next = new ListNode(4);
    head1->next->next->next = new ListNode(8);
    solution.Print_LinkList(head1);
    ListNode* head2 = new ListNode(1);
    head2->next = new ListNode(3);
    head2->next->next = new ListNode(4);
    solution.Print_LinkList(head2);
    ListNode* l = solution.mergeTwoLists(head1, head2);
    solution.Print_LinkList(l);

    // 释放内存,防止内存泄漏
    while (l != nullptr) {
        ListNode* temp = l;
        l = l->next;
        delete temp;
    }

    return 0;
}

2.3 使用递归

思路算法

  • 终止条件:当两个链表都为空时,表示我们对链表已合并完成。
  • 如何递归:我们判断 l1 和 l2 头结点哪个更小,然后较小结点的 next 指针指向其余结点的合并结果。(调用递归)

标签:ListNode,21,val,nullptr,list1,next,链表,有序,list2
From: https://www.cnblogs.com/trmbh12/p/17778152.html

相关文章

  • Adobe Audition 2021 for Mac中文直装版下载附安装激活步骤
    Audition2021ForMac缩写为Au2021,它是一款功能强大的整合音频编辑软件。使用该软件的用户不仅可以自由创建和编辑音频文件,还可以进行降噪处理、混音视频、录制播客或节目的声音、恢复和修复音频录音等功能,因此能够很好地满足用户的多种使用需求。软件地址:看置顶贴软件新功能:1.自......
  • 21.3 Python 使用DPKT分析数据包
    dpkt项目是一个Python模块,主要用于对网络数据包进行解析和操作。它可以处理多种协议,例如TCP、UDP、IP等,并提供了一些常用的网络操作功能,例如计算校验和、解析DNS数据包等。由于其简单易用的特性,dpkt被广泛应用于网络安全领域,例如流量分析、漏洞利用、入侵检测等。使用该库可以快速......
  • 石油管螺纹刀具,公司参加第十七届中国国际机床展览会(CIMT2021)
    成都工具研究所有限公司的前身是成都工具研究所,于1956年创建于北京,是原机械工业部的直属研究所,是我国机械工业的综合性工具科研机构。公司官网:http://www.ctri.com.cn/公司主要从事精密切削工具、精密测量仪器以及表面改性处理技术的技术研究、产品开发和应用服务。 4月12-17......
  • [Leetcode] 0083. 删除排序链表中的重复元素
    83.删除排序链表中的重复元素题目描述给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回已排序的链表 。 示例1:输入:head=[1,1,2]输出:[1,2]示例2:输入:head=[1,1,2,3,3]输出:[1,2,3] 提示:链表中节点数目在范围[0,300]......
  • 88. 合并两个有序数组
    给你两个按非递减顺序排列的整数数组nums1和nums2,另有两个整数m和n,分别表示nums1和nums2中的元素数目。请你合并nums2到nums1中,使合并后的数组同样按非递减顺序排列。注意:最终,合并后数组不应由函数返回,而是存储在数组nums1中。为了应对这种情况,nums1的初......
  • 数据结构-链表
    //节点classNode{constructor(element){this.element=elementthis.next=null}}//链表classLinkList{constructor(){this.size=0this.head=null}//根据index获取节点getNode(index){if(index<0||index>......
  • [COCI2021-2022#6] Zemljište
    [COCI2021-2022#6]Zemljište题目描述有一块地,大小为$r\timess$,$\rmMatej$想买下它。这块地每个$1\times1$的正方形都有不同的价格。设一片非空子矩阵价格总和为$m$,则这片子矩阵的权值为$|m-a|+|m-b|$,您需要找到最小权值的子矩阵。您只需要输出最小权值即可。输入......
  • 10.19~10.21
    10.19到这时候都不知道干啥了,很清楚要打板子,但是又不想打。一年没学oi给我的感觉就是“学了一年数学,脑子比以前灵光了”。人到了一定程度就开始相信玄学了,什么运气呀,rp啊,都信了。感觉以前的自己好sb,特别是博客园的那个sb头像,当时换了之后就将近一年没注意到,好尴尬,诸位好心人快......
  • 21.1 Python 使用PEfile分析PE文件
    PeFile模块是Python中一个强大的便携式第三方PE格式分析工具,用于解析和处理Windows可执行文件。该模块提供了一系列的API接口,使得用户可以通过Python脚本来读取和分析PE文件的结构,包括文件头、节表、导入表、导出表、资源表、重定位表等等。此外,PEfile模块还可以帮助用户进行一些恶......
  • 21.1 Python 使用PEfile分析PE文件
    PeFile模块是Python中一个强大的便携式第三方PE格式分析工具,用于解析和处理Windows可执行文件。该模块提供了一系列的API接口,使得用户可以通过Python脚本来读取和分析PE文件的结构,包括文件头、节表、导入表、导出表、资源表、重定位表等等。此外,PEfile模块还可以帮助用户进行一些......