链表算法篇——链接彼岸,流离节点的相遇之诗(下)

news2025/1/6 19:04:25

文章目录

  • 前言
  • 第一章:重排链表
    • 1.1 题目链接:https://leetcode.cn/problems/reorder-list/description/
    • 1.2 题目分析:
    • 1.3 思路讲解:
    • 1.4 代码实现:
  • 第二章:合并K个升序链表
    • 2.1 题目链接:https://leetcode.cn/problems/merge-k-sorted-lists/description/
    • 2.2 题目分析:
    • 2.3 思路讲解:
    • 2.4 代码实现:
  • 第三章:K个一组翻转链表
    • 3.1 题目链接:https://leetcode.cn/problems/reverse-nodes-in-k-group/description/
    • 3.2 题目分析:
    • 3.3 思路讲解:
    • 3.4 代码实现:
  • 第四章:现实世界中的链表——灵活性的代言人
  • 第五章:链表的优雅与局限
  • 尾声:链表的哲学——从离散到连贯

在这里插入图片描述

前言

上篇我们介绍了链表算法的相关概念,并结合基础题目加以讲解。本篇将通过三道进阶题目,进一步深化对于链表算法的掌握运用。

第一章:重排链表

1.1 题目链接:https://leetcode.cn/problems/reorder-list/description/

1.2 题目分析:

题目所要求的重组即为将后半部分链表逆序,之后逐个加入到前半部分链表中。

1.3 思路讲解:

  • 既然后半部分需要逆序,那么我们首先需要找到中间结点

逆序时直接采用头插法可大大简化步骤

  • 查找中间节点时,假设节点总数为奇数个,那么即为正中间的节点
  • 若节点总数为偶数个,则可采取靠右的中间节点,该中点的下一个节点开始即为后半部分需要重排的链表
    在这里插入图片描述
    此时3为中间结点,重排结果如下:
    在这里插入图片描述

1.4 代码实现:

class Solution {
public:
    void reorderList(ListNode* head) {
        ListNode* newhead=new ListNode(0);//哨兵位
        newhead->next=head;
        ListNode* slow=head,*fast=head;
        //查找中间节点
        while(fast&&fast->next)
        {
            slow=slow->next;
            fast=fast->next->next;
        }
        ListNode* cur1=head,*cur2=slow->next;//前后两部分链表头
        slow->next=nullptr;//断开两部分链接
        //将后半部分链表逆序
        ListNode* head2=new ListNode(0);
        while(cur2)
        {
            ListNode* next=cur2->next;
            cur2->next=head2->next;
            head2->next=cur2;
            cur2=next;
        }
        cur2=head2->next;
        ListNode* cur=newhead;
        //合并
        while(cur1||cur2)
        {
            if(cur1)
            {
                cur->next=cur1;
                cur=cur1;
                cur1=cur1->next;
              
            }
            if(cur2)
            {
                cur->next=cur2;
                cur=cur2;
                cur2=cur2->next;
            }

        }
        
        
    }
};

第二章:合并K个升序链表

2.1 题目链接:https://leetcode.cn/problems/merge-k-sorted-lists/description/

2.2 题目分析:

  • 题目给定K个升序链表,要求将其合并为一个总的升序链表
  • 必须进行节点的依次修改连接,而非单纯修改值

2.3 思路讲解:

此题的核心在于每一个链表自身已经是升序排列。

  • 我们可以采用优先级队列priority_queue,建立一个小根堆,将各个链表的头节点依次入堆。
  • 由于链表为自定义类型,还需要我们定义一个比较函数
  • 此时堆内已经按照节点大小依次排列,之后持续出堆进堆即可完成合并排序。

2.4 代码实现:

class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        //自定义比较函数
        struct cmp
        {
            bool operator() (const ListNode* l1,const ListNode* l2)
            {
                return l1->val>l2->val;
            }
        };
        //建立小根堆
        priority_queue<ListNode*,vector<ListNode*>,cmp> min;
        for(auto e:lists)
        {
            if(e)
            min.push(e);
        }
        ListNode* newhead=new ListNode(0);
        ListNode* cur=newhead;
        while(!min.empty())
        {
            ListNode* newnode=min.top();
            min.pop();
            if(newnode->next)
            min.push(newnode->next);//进出操作
            cur->next=newnode;
            cur=newnode;//连接

        }
        return newhead->next;
    }
};

第三章:K个一组翻转链表

3.1 题目链接:https://leetcode.cn/problems/reverse-nodes-in-k-group/description/

3.2 题目分析:

  • 现给定链表,要求每k个节点进行一次逆序重排
  • 剩余不足K的节点按照原顺序链接
  • 必须修改节点连接,而非单纯修改节点的值

3.3 思路讲解:

本题的核心操作即为逆序,而逆序我们已经了解了一种极为便捷的方法——头插。

  • 我们可以首先计算出需要翻转的次数,若节点个数为n,则翻转次数为n/k。
  • 此后进行n/k次翻转并依次连接即可。

3.4 代码实现:

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        int n=0;
        ListNode* cur=head;
        while(cur)
        {
            n++;
            cur=cur->next;
        }//计算节点个数
        n/=k;//计算翻转次数
        ListNode* newhead=new ListNode(0);
        ListNode* prev=newhead;
        cur=head;
       for(int j=0;j<n;j++)
       {
            //逆序
            ListNode* temp=cur;
            for(int i=0;i<k;i++)
            {
                ListNode* next=cur->next;
                cur->next=prev->next;
                prev->next=cur;
                cur=next;

            }
            prev=temp;

        }
        //连接剩余部分
        if(cur)
        prev->next=cur;
        prev=newhead->next;
        delete newhead;
        return prev;

        
        
    }
};

第四章:现实世界中的链表——灵活性的代言人

链表不仅是理论的产物,它在实际应用中发挥着不可替代的作用。许多复杂数据结构和算法的基础都源于链表的思想:

LRU缓存
使用双链表实现最近最少使用(LRU)缓存,可以高效地实现插入、删除和访问操作,是操作系统和数据库中广泛应用的算法。

动态内存管理
在操作系统中,链表被用来实现内存分配的自由链表(Free List),以动态追踪可用的内存块。

图与树的表示
图和树的邻接表表示常常依赖链表,以节省存储空间并保持访问灵活性。

第五章:链表的优雅与局限

尽管链表算法有着灵活动态的特性,但它并非完美无瑕。链表的局限性同样值得我们思考:

  • 随机访问效率低:由于链表无法像数组那样通过索引直接访问元素,因此查找操作可能需要耗费较多时间。
  • 额外存储开销:每个节点都需要存储额外的指针,占用更多内存。

然而,正是这些局限,使链表在适合的场景中更加熠熠生辉。

尾声:链表的哲学——从离散到连贯

链表算法的魅力在于它的灵活与动态,它不仅仅是一个数据结构,更是一种哲学思考——如何将孤立的事物通过简单的连接,构成一片完整的世界。从单链表到双链表,从循环链表到跳跃表,链表的多样性和适应性启发我们:在设计系统与算法时,学会连接、适应与创造,方能构建出优雅而高效的解决方案。

链表,是数据结构的诗篇,它用指针为每一个节点赋予意义,用算法为每一个节点找到归属。或许,这正是计算机科学的浪漫之处。

本篇关于链表算法的讲解就暂告段落啦,希望能对大家的学习产生帮助,欢迎各位佬前来支持斧正!!!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2271039.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WebRTC的线程事件处理

1. 不同平台下处理事件的API&#xff1a; Linux系统下&#xff0c;处理事件的API是epoll或者select&#xff1b;Windows系统下&#xff0c;处理事件的API是WSAEventSelect&#xff0c;完全端口&#xff1b;Mac系统下&#xff0c;kqueue 2. WebRTC下的事件处理类&#xff1a; …

【Cocos TypeScript 零基础 4.1】

目录 背景滚动 背景滚动 创建一个 空节点 背景丟进去 ( 复制一个,再丢一次都行) 新建TS脚本 并绑定到 空节点 上 再对TS脚本进行编辑 export class TS2bg extends Component {property (Node) // 通过属性面板去赋值bg1:Node nullproperty (Node) bg2:Node nullprope…

利用 AI 高效生成思维导图的简单实用方法

#工作记录 适用于不支持直接生成思维导图的AI工具&#xff1b;适用于AI生成后不能再次编辑的思维导图。 在日常的学习、工作以及知识整理过程中&#xff0c;思维导图是一种非常实用的工具&#xff0c;能够帮助我们清晰地梳理思路、归纳要点。而借助 AI 的强大能力&#xff0c…

AfuseKt1.4.4 | 刮削视频播放器,支持阿里云盘和自动海报墙

AfuseKt是一款功能强大的安卓端在线视频播放器&#xff0c;广泛兼容多种平台如阿里云盘、Alist、WebDAV、Emby、Jellyfin等&#xff0c;同时也支持本地存储视频文件的播放。其特色功能包括自动抓取影片信息生成海报墙展示&#xff0c;充分利用设备硬件进行高清视频流畅播放&…

Linux下部署ElasticSearch集群

Elasticsearch7.17.8集群的搭建 节点host名称节点ip节点部署内容k8s-m192.168.40.142主节点 数据节点k8s-w1192.168.40.141主节点 数据节点k8s-w2192.168.40.140数据节点 一、准备安装环境 1.下载安装包 官网 www.elastic.co 下载所有版本地址 点击跳转 下载elasticsearch-7.…

covid-vaccine-availability-using-flask-server

使用烧瓶服务器获得 Covid 疫苗 原文:https://www . geesforgeks . org/co vid-疫苗-可用性-使用-烧瓶-服务器/ 在本文中&#xff0c;我们将使用 Flask Server 构建 Covid 疫苗可用性检查器。 我们都知道&#xff0c;整个世界都在遭受疫情病毒的折磨&#xff0c;唯一能帮助我们…

线性变换在机器学习中的应用实例

一、线性变换的基本概念 线性变换是指将一个向量空间中的向量映射到另一个向量空间中的函数&#xff0c;这种映射关系保持向量加法和标量乘法的运算性质。在机器学习中&#xff0c;线性变换通常通过矩阵乘法来实现&#xff0c;其中输入向量被视为列向量&#xff0c;矩阵被视为…

【Linux】传输层协议UDP

目录 再谈端口号 端口号范围划分 UDP协议 UDP协议端格式 UDP的特点 UDP的缓冲区 UDP注意事项 进一步深刻理解 再谈端口号 在上图中&#xff0c;有两个客户端A和B&#xff0c;客户端A打开了两个浏览器&#xff0c;这两个客户端都访问同一个服务器&#xff0c;都访问服务…

大功率PCB设计

1.电源和电机的走线用线径较大的铺铜&#xff0c;讲究的是走线顺畅&#xff1a; 2.同一个电源属性四层板都铺铜&#xff0c;并打很多过孔: 3.走线顺畅&#xff0c;可以看到从左到右供电。从右向左接地&#xff0c;加电流采样&#xff1a; 一个问题&#xff0c;这样会形成电源环…

ArkTs之NAPI学习

1.Node-api组成架构 为了应对日常开发经的网络通信、串口访问、多媒体解码、传感器数据收集等模块&#xff0c;这些模块大多数是使用c接口实现的&#xff0c;arkts侧如果想使用这些能力&#xff0c;就需要使用node-api这样一套接口去桥接c代码。Node-api整体的架构图如下&…

Vue el-data-picker选中开始时间,结束时间自动加半小时

效果 思路 查阅elemnet plus官网&#xff0c;日期时间选择器type"datetimerange"这个选中开始时间并没有对应事件会被触发&#xff0c;因此思路更换成type"datetime"的两个组成一起可以通过监听开始时间v-model的值变化更新结束时间的值。 代码 日期时间…

gitlab高级功能之 CICD Steps

CICD Steps 1. 介绍2. 定义 Steps2.1 Inputs2.2 Outputs 3. Using steps3.1 Set environment variables3.2 Running steps locally 4. Scripts5. Actions5.1 已知的问题 6. 表达式7. 实操7.1 单个step7.2 多个step7.3 复用steps7.4 添加output到step7.5 使用远程step 1. 介绍 …

TVS二极管选型【EMC】

TVS器件并联在电路中&#xff0c;当电路正常工作时&#xff0c;他处于截止状态&#xff08;高阻态&#xff09;&#xff0c;不影响线路正常工作&#xff0c;当线路处于异常过压并达到其击穿电压时&#xff0c;他迅速由高阻态变为低阻态&#xff0c;给瞬间电流提供一个低阻抗导通…

122.【C语言】数据结构之快速排序(Hoare排序的优化)

目录 1.解决方法(即优化方法) 方法1.随机选key 运行结果 方法2:三数取中 1.含义 2.做法 3.代码 1.若arr[left] < arr[mid_i],则arr[right]可能的位置也有三处 2.若arr[left] > arr[mid_i],则arr[right]可能的位置也有三处 2.证明当key_ileft时,right先走,使left…

Golang的容器编排实践

Golang的容器编排实践 一、Golang中的容器编排概述 作为一种高效的编程语言&#xff0c;其在容器编排领域也有着广泛的运用。容器编排是指利用自动化工具对容器化的应用进行部署、管理和扩展的过程&#xff0c;典型的容器编排工具包括Docker Swarm、Kubernetes等。在Golang中&a…

《Spring Framework实战》2:Spring快速入门

欢迎观看《Spring Framework实战》视频教程 Spring快速入门 目录 1. Java™开发套件&#xff08;JDK&#xff09; 2. 集成开发人员环境&#xff08;IDE&#xff09; 3. 安装Maven 4. Spring快速入门 4.1. 开始一个新的Spring Boot项目 4.2. 添加您的代码 4.3. 尝…

HTML——66.单选框

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>单选框</title></head><body><!--input元素的type属性&#xff1a;(必须要有)--> <!--单选框:&#xff08;如所住省会&#xff0c;性别选择&…

rouyi(前后端分离版本)配置

从gitee上下载&#xff0c;复制下载地址&#xff0c;到 点击Clone&#xff0c;下载完成&#xff0c; 先运行后端&#xff0c;在运行前端 运行后端&#xff1a; 1.配置数据库&#xff0c;在Navicat软件中&#xff0c;连接->mysql->名字自己起(rouyi-vue-blog),用户名roo…

基于云架构Web端的工业MES系统:赋能制造业数字化变革

基于云架构Web端的工业MES系统:赋能制造业数字化变革 在当今数字化浪潮席卷全球的背景下,制造业作为国家经济发展的重要支柱产业,正面临着前所未有的机遇与挑战。市场需求的快速变化、客户个性化定制要求的日益提高以及全球竞争的愈发激烈,都促使制造企业必须寻求更加高效、智…

如何解决电脑提示缺失kernel32.dll文件错误,kernel32.dll文件缺失、损坏或错误加载问题解决方案

电脑运行故障深度解析&#xff1a;从文件丢失到系统报错&#xff0c;全面应对kernel32.dll问题 在数字化时代&#xff0c;电脑已经成为我们日常生活和工作中不可或缺的工具。然而&#xff0c;电脑在长时间运行过程中&#xff0c;难免会遇到各种问题&#xff0c;如文件丢失、文…