算法笔记(六)——链表

news2024/10/6 4:45:43

文章目录

  • 两数相加
  • 两两交换链表中的节点
  • 重排链表
  • 合并 K 个升序链表
  • K个一组翻转链表

技巧:

  1. 画图观察指针指向;
  2. 添加虚拟头节点;
  3. 可以多定义几个节点;
  4. 快慢双指针;

常见操作:

  1. 定义new head
  2. 逆序时,头插
ListNode* newhead = new ListNode(0);
ListNode* cur= head;
ListNode* next = cur->next;
cur->next = head->next;
head->next = cur;
cur = 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* addTwoNumbers(ListNode* l1, ListNode* l2) 
    {
        ListNode* newhead = new ListNode(-1);
        ListNode* prev = newhead;
        ListNode* cur1 = l1;
        ListNode* cur2 = l2;

        int t = 0;

        while(cur1 || cur2 || t)
        {
            if(cur1)
            {
                t += cur1->val;
                cur1 = cur1->next;
            }
            if(cur2)
            {
                t += cur2->val;
                cur2 = cur2->next;
            }

            prev->next = new ListNode(t % 10);
            prev = prev->next;
            t /= 10;
        }

        prev = newhead->next;
        delete newhead;
   
        return prev;
    }
};

两两交换链表中的节点

题目:两两交换链表中的节点

在这里插入图片描述
思路
在这里插入图片描述
循环终止条件

  • 奇节点数,next == NUL
  • 偶节点数,cur == NULL

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* swapPairs(ListNode* head) 
    {
        if(head == nullptr || head->next == nullptr) 
            return head;

        ListNode* newhead=new ListNode();
        newhead->next = head;

        ListNode* prev = newhead;
        ListNode* cur = prev->next, *next = cur->next, *nnext = next->next;

        while(cur && next)
        {
            // 重新连接节点(顺序无所谓)
            prev->next = next;
            next->next = cur;
            cur->next = nnext;

            // 迭代节点(注意顺序)
            prev = cur;
            cur = nnext;
            if(cur) next = cur->next;
            if(next) nnext = next->next;
        }
        prev=newhead->next;
        delete newhead;
        return prev;
    }
};

重排链表

题目:重排链表

在这里插入图片描述

思路

  • 模拟
    1. 找到链表的中间节点; 快慢双指针
    1. 逆序后面的链表;头插
    1. 合并两个链表;双指针

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) {}
 * };
 */
/**
 * 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:
    void reorderList(ListNode* head) 
    {

        ListNode* slow = head;
        ListNode* fast = head->next;
        while (fast && fast->next) 
        {
            slow = slow->next;
            fast = fast->next->next;
        }

        //反转后半段链表
        ListNode* second = reverseList(slow->next);
        slow->next = nullptr;
        ListNode* first = head;

        //交替合并first和second
        while (second) 
        {
            ListNode* tmpNode1 = first->next;
            ListNode* tmpNode2 = second->next;
            first->next = second;
            second->next = tmpNode1;
            first = tmpNode1;
            second = tmpNode2;
        }
    }

     ListNode* reverseList(ListNode* head) 
     {

        if (head == nullptr) return head;
        
        ListNode* prev = nullptr;
        ListNode* cur = head;
        while (cur)
        {
            ListNode* tmp = cur->next;
            cur->next = prev;
            prev = cur;
            cur = tmp;
        }

        return prev;
    }
};


合并 K 个升序链表

题目:合并 K 个升序链表

在这里插入图片描述
思路

  • 将每个链表的头节点入小堆,每次从堆顶元素开始链接,逐个将堆顶的最小链表节点链接,并不断向堆中添加后续元素;

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:
    struct cmp
    {
        bool operator()(const ListNode* l1,const ListNode* l2)
        {
            return l1->val > l2->val;
        }
    };
    ListNode* mergeKLists(vector<ListNode*>& lists) 
    {   
        // 小堆
        priority_queue<ListNode*,vector<ListNode*>, cmp> heap;

        // 所有头节点进堆
        for(auto l : lists)
            if(l) heap.push(l);

        // 合并
        ListNode* ret = new ListNode(0);
        ListNode* prev = ret;

        while(!heap.empty())
        {
            ListNode* t = heap.top();
            heap.pop();
            prev->next = t;  
            prev = t;
            if(t->next != nullptr) heap.push(t->next);

        }

        prev = ret->next;
        delete ret;
        return prev;
    }
};

K个一组翻转链表

题目:K 个一组翻转链表

在这里插入图片描述
思路

  • 计算需要翻转的次数
  • 重复 n 次,长度为 k 的链表的逆序

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* reverseKGroup(ListNode* head, int k) 
    {
        // 统计节点个数
        int n = 0;
        ListNode* cur = head;
        while(cur)
        {
            n++;
            cur = cur->next;
        }
        n /= k;

        // 重复n次长度为k的链表逆序
        ListNode* newhead = new ListNode(0);
        ListNode* prev = newhead;
        cur = head;
        for(int i = 0; i < n; i++)
        {
            ListNode* tmp = cur;
            for(int j = 0; j < k; j++)
            {
                ListNode* next = cur->next;
                cur->next = prev->next;
                prev->next = cur;
                cur = next;
            }
            prev = tmp;
        }
        prev->next = cur;

        return newhead->next;
    }
};

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

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

相关文章

带你深入浅出设计模式:八、适配器模式:代码世界中的万能转换器

此为设计模式第八谈&#xff01; 用总-分-总的结构和生活化的例子给你讲解设计模式&#xff01; 码农不易&#xff0c;各位学者学到东西请点赞收藏支持支持&#xff01; 开始部分&#xff1a; 总&#xff1a;适配器模式主要解决的问题是已有类的接口与所需的接口不匹配的问题…

[Python学习日记-38] Python 中的函数的名称空间

[Python学习日记-38] Python 中的函数的名称空间 简介 名称空间 作用域查找顺序 简介 在前面学习函数的时候我们发现&#xff0c;函数内部也有一个内存空间是用于存储函数自己的一些变量的&#xff0c;及时这个变量名与外部的变量名一样是也没关系&#xff0c;Python 会优先…

CGLib动态代理和JDK动态代理Demo、ASM技术尝鲜

本文主要介绍CGLib和JDK动态代理的使用&#xff0c;不对源码进行深入分析。代码可直接复制使用。 类型 机制 回调方式 适用场景 效率 JDK动态代理 委托机制。代理类和目标类都实现了同样的接口。InvocationHandler持有目标类。代理类委托InvocationHandler去调用目标类原…

令牌主动失效机制范例(利用redis)注释分析

介绍该机制 令牌生成 在需要限流的场景中&#xff0c;系统会根据一定的速率生成令牌&#xff0c;存储在 Redis 中。可以设定每秒生成的令牌数量。 令牌获取 当用户请求时&#xff0c;系统会从 Redis 中获取令牌。可以使用原子性操作&#xff08;如 DECR&#xff09;来确保令牌…

SHAP分析

SHAP分析&#xff08;SHapley Additive exPlanations&#xff09;是一种基于博弈论的解释机器学习模型输出的方法。它提供了一种统一的方式来解释模型的预测结果&#xff0c;量化每个特征对模型预测的贡献&#xff0c;能够为复杂的机器学习模型&#xff08;如随机森林、梯度提升…

C语言基础(8)之操作符(2)(详解)

目录 1. 操作符汇总表 2. 关系操作符 3. 条件操作符 4. 逗号表达式 5. 下标引用、函数调用和结构成员 5.1 下标引用 5.2 函数调用操作符 5.3 结构成员 6. 操作符的属性 6.1 操作符的优先级 大家好呀&#xff01;上篇文章中我们详细讲解了操作符的前半部分&#xff0c…

【成长day】SuperPointSuperGlue(01): Superpoint论文算法学习与对应源码解析

两年前自己在实习公司做过superpoint相关的工作&#xff0c;当时是负责利用superpoint代替slam前端的特征点部分&#xff0c;来达到把特征点相关的处理放到推理计算平台上减轻CPU压力并且精度无损的目的&#xff0c;最终也是成功完成了这部分工作。但是当时没有留下任何的记录&…

YOLOv8 基于MGD的知识蒸馏

YOLOv8 基于MGD的知识蒸馏 接着上一篇我们介绍了YOLOv8的剪枝方案和代码&#xff0c;本篇文章将剪枝后的模型作为学生模型&#xff0c;剪枝前的模型作为教师模型对剪枝模型进行蒸馏&#xff0c;从而进一步提到轻量模型的性能。 Channel-wise Distillation (CWD) 问题和方法 …

IDM下载器如何下载网盘文件 IDM下载器支持哪些网盘

不用开通会员&#xff0c;也能高速下载网盘文件。使用IDM下载加速器&#xff0c;直接从服务器高速下载文件&#xff0c;轻松突破网盘限速。掌握IDM下载网盘文件的技巧&#xff0c;不仅可以节省会员费用&#xff0c;还可以大幅提高下载效率。有关IDM下载器如何下载网盘文件&…

【Linux:线程控制】

目录 线程的创建与等待&#xff1a; ​编辑 代码中tid是什么&#xff1f; 如何看待线程函数传参&#xff1f; ​编辑 ​编辑创建多线程&#xff1a;​编辑 终止多线程&#xff1a; 线程分离&#xff1a; 线程的创建与等待&#xff1a; void *threadrun(void *args) {int …

QT 中如何保存matlab 能打开的.mat数据矩阵!

Windows 上安装并使用 MATIO 库来保存 MATLAB 格式的 .mat 文件&#xff0c;需要进行以下步骤&#xff1a; 1. 下载并安装 CMake MATIO 使用 CMake 构建项目&#xff0c;因此你需要先安装 CMake。 前往 CMake 官网下载适用于 Windows 的安装程序并安装。 2. 下载 MATIO 库源…

Unity基础-矩阵-坐标转换结果的个人理解+数学公式说明

想做一些渲染效果做到头大&#xff0c;根本很多空白&#xff0c;完全无法实现&#xff0c;只能先暂停一下&#xff0c;重新学习矩阵 目录 Unity基础-数学矩阵 1.我们利用最简单的“转换矩阵”&#xff0c; 2.然后&#xff0c;视图坐标又是如何 3.最后就是剪裁坐标 3.1 - 其…

硬件设计-利用环路设计优化PLL的输出性能

目录 前言 问题描述 问题分析步骤 杂散源头排查 245.76M 参考相噪&#xff1a; 30.72M VCXO的相噪性能测试如下: 解决方案 前言 LMK04832是TI 新发布的低抖动双环去抖模拟时钟&#xff0c; 其最高输出频率可以到达3250MHz&#xff0c; 输出抖动极低&#xff0c;3200MHz…

MySQL 中的数据库锁和表锁

在 MySQL 数据库中&#xff0c;为了保证数据的一致性和完整性&#xff0c;会使用各种类型的锁。其中&#xff0c;数据库锁和表锁是比较常见的两种锁类型。 一、数据库锁和表锁的概念 &#xff08;一&#xff09;数据库锁 数据库锁是对整个数据库进行锁定&#xff0c;限制对数…

尝试从 http://pypi.doubanio.com/simple 这个索引源安装 webdriver 时出现了问题

问题如下&#xff1a; WARNING: The repository located at pypi.doubanio.com is not a trusted or secure host and is being ignored. If this repository is available via HTTPS we recommend you use HTTPS instead, otherwise you may silence this warning and allow …

ElasticSearch备考 -- 异步检索

一、题目 通过异步方式查询earthquakes索引下Magnitude大于5的数据 二、思考 正常的查询大家可能会用的多一点&#xff0c;这种异步查询为了可以数据量量比较大的查询在后台执行&#xff0c;不用同步等待结果&#xff0c;待执行完成在获取结果。 三、解题 Step 1、准备基础数…

【深度强化学习基础】(一)基本概念

【深度强化学习基础】&#xff08;一&#xff09;基本概念 一、概率论基础知识二、强化学习领域术语三、强化学习中两个随机性的来源&#xff1a;四、rewards以及returns五、Value Functions1.Action-Value Function Q π ( s , a ) Q_\pi(s,a) Qπ​(s,a)1.State-Value Funct…

Yolov8改进WIoU,SIoU,EIoU,α-IoU

1,IOU原理部分 IoU(Intersection over Union)是一种在计算机视觉领域常用的性能评估指标,尤其在目标检测和图像分割任务中。它通过计算预测边界框(预测框)与真实边界框(真实框)之间的交集面积与并集面积之比来衡量预测的准确性。IoU的值越接近1,表示预测框与真实框的重…

Error while loading conda entry point: conda-libmamba-solver

问题 解决方法 conda install --solverclassic conda-forge::conda-libmamba-solver conda-forge::libmamba conda-forge::libmambapy conda-forge::libarchive

C0015.Clion中开发C++时,连接Mysql数据库方法

安装mysql数据库 CMakeLists.txt中配置mysql数据库 # 先指定mysql数据库的安装位置 include_directories("C:/Program Files/MySQL/MySQL Server 8.0/include") link_directories("C:/Program Files/MySQL/MySQL Server 8.0/lib") link_libraries(libmysq…