【刷题13】链表专题

news2024/11/23 21:29:02

目录

  • 一、两数相加
  • 二、两两交换链表的节点
  • 三、重排链表
  • 四、合并k个升序链表
  • 五、k个一组翻转链表

一、两数相加

题目:
在这里插入图片描述

思路:

  • 注意整数是逆序存储的,结果要按照题目的要求用链表连接起来
  • 遍历l1的cur1,遍历l2的cur2,和一个整数t,用来表示进位(t等于1,要进位;t等于0,不需要进位)
  • 先固定好头节点newhead,所以cur1和cur2指向的val先要运算。为什么要先固定好头节点,因为方便后面尾插
  • 相加的结果为变量tmp,如果>=10,就取后面的数(%10),并且t=1;否则直接用相加后的tmp来构造节点的值,t还是0
  • 进入循环条件,只要cur1、cur2、t任意一个不为空(t不等于0),就能进入循环,有节点,就加节点的值,没节点就用进位
  • 循环中,每次的tmp要刷新为0,cur1不为空,tmp+=cur1->val,cur1往后走;cur2不为空,tmp+=cur2->val,cur2往后走;t等于1,说明有进位,tmp+=1。如果tmp>=10,tmp取后面的数,t = 1;否则还是相加后的tmp,t = 0;
  • 然后构造新节点,val为tmp,尾插
  • 循环后,tail->next 记得置为空(最好),返回newhead

代码:

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* cur1 = l1;
        ListNode* cur2 = l2;
        int t = 0;// 进位
        int tmp = cur1->val + cur2->val;
        cur1 = cur1->next;
        cur2 = cur2->next;
        if(tmp >= 10)
        {
            t = 1;
            tmp %= 10;
        }
        ListNode* newhead = new ListNode(tmp);
        ListNode* tail = newhead;
        while(cur1 || cur2 || t)
        {
            tmp = 0;
            if(cur1 != nullptr) 
            {
                tmp += cur1->val;
                cur1 = cur1->next;
            }
            if(cur2 != nullptr) 
            {
                tmp += cur2->val;
                cur2 = cur2->next;
            }
            if(t) tmp += t;

            if(tmp >= 10)
            {
                t = 1;
                tmp %= 10;
            } 
            else t = 0;

            ListNode* newnode = new ListNode(tmp);
            tail->next = newnode;
            tail = tail->next;
        }
        tail->next = nullptr;
        return newhead;
    }
};

二、两两交换链表的节点

题目:
在这里插入图片描述
解法一: 交换值(能过)
思路:

  • 链表为空,返回空
  • 链表只有一个节点,返回该链表
  • 链表大于1个节点:prev指向第一个节点,cur指向第二个节点,循环为cur不为空
  • 进入循环,cur和prev的节点值交换,然后prev指向cur的下一个节点,如果prev不为空,cur指向prev的下一个节点(相当于走了两步);否则直接跳出循环
  • 然后原来的链表

代码:

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(head == nullptr) return nullptr;
        if(head->next == nullptr) return head;
        ListNode* cur = head->next;
        ListNode* prev = head;
        while(cur)
        {
            int t = cur->val;
            cur->val = prev->val;
            prev->val = t;
            prev = cur->next;
            if(prev == nullptr) break;
            cur = prev->next;
        }
        return head;
    }
};

解法二: 交换节点
思路:

  • 如果为空链表或者链表只有一个节点,直接返回head
  • 定义一个哨兵位头节点,方便后续连接操作
  • 定义4个指针:
    在这里插入图片描述
  • 注意连接顺序和可能为空的情况
  • 让head重新指向修改后的tmp的next,销毁tmp,返回head

代码:

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(head == nullptr || head->next == nullptr) return head;
        ListNode* tmp = new ListNode(0);
        tmp->next = head;
        ListNode* prev = tmp;
        ListNode* cur = head;
        ListNode* next = cur->next;
        ListNode* 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;
        }
        head = tmp->next;//
        delete tmp;
        return head;
    }
};

三、重排链表

题目:
在这里插入图片描述
思路:
在这里插入图片描述

  • 找到中间节点,中间节点之后逆序,然后如图先h1插入节点,再h2插入节点
  • 如果链表的节点只有一个,还是原来的链表
  • 找到中间节点——快慢双指针法
  • 链表逆序——头插法
  • 定义newhead为head,先固定第一个节点。h1为中间节点后逆序的链表,h2为head的下一个节点
  • h1不为空,尾插h1的节点;h2不为slow(因为slow指向的是中间节点的位置)尾插h2的节点
  • 循环结束,tail->next等于空,head=newhead,即还原head

代码:

class Solution {
public:
    void reorderList(ListNode* head) {
        if(head->next == nullptr) head = head;
        else 
        {
            ListNode* slow = head;
            ListNode* fast = head;
            while(fast && fast->next)
            {
                slow = slow->next;
                fast = fast->next->next;
            } 
            ListNode* mid = slow;
            ListNode* h1 = nullptr;
            while(mid)
            {
                ListNode* next = mid->next;
                mid->next = h1;
                h1 = mid;
                mid = next;
            }
            ListNode* h2 = head->next;
            ListNode* newhead = head;
            ListNode* tail = newhead;
            while(h1)
            {
                tail->next = h1;
                tail = tail->next;
                h1 = h1->next;

                if(h2 != slow)
                {
                    tail->next = h2;
                    tail = tail->next;
                    h2 = h2->next;
                }
            }
            tail->next = nullptr;
            head = newhead;
        }
    }
};

四、合并k个升序链表

题目:
在这里插入图片描述
思路:
小堆,所有的链表的节点放入小堆,然后取顶部依次尾插(注意:要考虑链表的某个节点可能为空的情况)

代码:

class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        priority_queue<int, vector<int>, greater<int>> pq;// 小堆
        ListNode* newhead =nullptr;
        ListNode* tail= nullptr;
        // k * n=500(节点数)
        for(auto &l : lists)
        {
            if(l)
            {
                ListNode* cur = l;
                while(cur)
                {
                    pq.push(cur->val);
                    cur = cur->next;
                }
            }
        }
        // log(n*k) => log(k)
        while(!pq.empty())
        {
            int t = pq.top();
            ListNode* newnode = new ListNode(t);
            if(tail == nullptr)
            {
                tail = newhead = newnode;
            }
            else 
            {
                tail->next = newnode;
                tail = tail->next;
            }
            pq.pop();
        }
        return newhead;
    }
};

五、k个一组翻转链表

题目:
在这里插入图片描述

思路:

  • 两层循环,外面是翻转的组的个数,里面的一组的节点数(头插法)
  • 先用哨兵位节点newhead固定,然后接下来每组的节点翻转后尾插到新的节点后面(刚开始是哨兵位节点,后面是上一组第一个头插的节点)
  • 最后返回newhead的下一个节点,记得循环哨兵位节点

代码:

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode* newhead = new ListNode(0);// 哨兵位节点先固定,方便后面连接
        ListNode* tail = newhead;// 方便找尾
        int n = 0;// 节点数
        ListNode* cur = head;// 遍历链表
        while(cur)
        {
            n++;
            cur = cur->next;
        }
        n /= k;// 翻转的组的个数
        int y = k;// 为了还原原来的k值
        // 
        cur = head;// 回到第一个节点
        while(n--)// 循环组数
        {
            ListNode* tmphead = nullptr;// 临时的头指针
            // 头插法
            while(k--)// 循环要翻转(头插)的节点数
            {
                ListNode* next = cur->next;
                cur->next = tmphead;
                tmphead = cur;
                cur = next;
            }
            k = y;// 还原k
            tail->next = tmphead;// 连接翻转的后一组子链表
            // 找到尾节点,方便下次尾插新的一组子链表
            while(tail->next)
            {
                tail = tail->next;
            }
        }
        tail->next = cur;// 尾插剩余的节点
        while(tail->next)
        {
            tail = tail->next;
        }
        tail->next = nullptr;// 
        ListNode* ret = newhead->next;// 要返回的链表
        delete newhead;//
        return ret;
    }
};

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

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

相关文章

人工智能与数据安全:Facebook如何应对隐私挑战

在数字时代&#xff0c;数据隐私和安全成为了用户和企业关注的核心问题。作为全球最大的社交媒体平台之一&#xff0c;Facebook面临着日益严峻的隐私挑战。近年来&#xff0c;频繁发生的数据泄露事件和对用户隐私的质疑&#xff0c;使得Facebook在保护用户数据方面倍感压力。为…

凸极式发电机的相量图分析和计算,内功率因数角和外功率因数角和功角的定义。

图1&#xff1a;同步发电机稳态相量图 若发电机为凸极式&#xff0c;由于凸极机正、交轴同步电抗不等&#xff0c;即xd≠xq&#xff0c;因此必须先借助虚构电动势 E ˙ Q E ˙ q − ( x d − x q ) I ˙ d \dot{E}_Q\dot{E}_q-(x_d-x_q)\dot{I}_d E˙Q​E˙q​−(xd​−xq​)…

C语言模拟实现堆排序

堆排序是一种效率比较高的排序方法&#xff0c;时间复杂度。 堆分为大堆和小堆&#xff0c;如果想要拍升序我们需要建立大堆&#xff0c;而如果想要拍降序则需要建立小堆&#xff0c;在使用堆排序前需要先建立一个堆&#xff0c;如果不会建立可以看我前面写的C语言模拟实现堆的…

HCIA笔记整合

第一部分&#xff1a; OSI七层模型 应用层&#xff1a;人机交互 抽象语言--------编码 表示层&#xff1a;编码------二进制 会话层&#xff1a;提供会话号 传输层&#xff1a;TCP/UDP 分段&#xff08;收到MTU值的限制&#xff09; MTU&#xff1a;最大传输单元&#xff…

html简易流程图

效果图 使用htmlcssjs&#xff0c;无图片&#xff0c;没用Canvas demo: <!DOCTYPE html> <html> <head><link href"draw.css" rel"stylesheet" /><script src"draw.js" type"text/javascript"></…

新手BUG:在声明了返回值的函数中不写返回值

本文对两个分别以int和string为返回值类型的函数进行分析&#xff0c;说明了在有返回值的函数中不写返回值会产生的问题。然后给出在编译阶段检查出这样的问题的办法。 一、背景 在软件测试环节发现&#xff0c;函数会在返回之前coredump。经过排查发现&#xff0c;在这个会…

单个相机矫正畸变

1、通过标定助手获取到内参外参&#xff0c;外参在此无效&#xff0c;只用到了内参 2、然后通过halcon算子进行矫正 参考&#xff1a;超人视觉

【骑士放置——最大独立集】

题目 思路 最大独立集n-最小点覆盖n-最大边匹配 代码 #include <bits/stdc.h> using namespace std; #define x first #define y second typedef pair<int, int> PII; const int N 110; int dx[8] {-2, -1, 1, 2, 2, 1, -1, -2}; int dy[8] {1, 2, 2, 1, -1, …

【每日题解】3226. 使两个整数相等的位更改次数

给你两个正整数 n 和 k。 你可以选择 n 的 二进制表示 中任意一个值为 1 的位&#xff0c;并将其改为 0。 返回使得 n 等于 k 所需要的更改次数。如果无法实现&#xff0c;返回 -1。 示例 1&#xff1a; 输入&#xff1a; n 13, k 4 输出&#xff1a; 2 解释&#xff1a…

使用Docker Swarm进行集群管理

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 使用Docker Swarm进行集群管理 引言 Docker Swarm 简介 安装 Docker Ubuntu CentOS 初始化 Swarm 集群 加入 Worker 节点 验证集…

SPA和SSR

单页面应用程序(SPA) 单页面应用(SPA)全称是:Single-page application, SPA应用是在客户端呈现的(术语称:CRS)。 SPA应用默认只返回一个空HTML页面&#xff0c;如:body只有<div id"app"></div>而整个应用程序的内容都是通过JavaScript动态加载&#xf…

初始JavaEE篇——多线程(4):wait、notify,饿汉模式,懒汉模式,指令重排序

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaEE 目录 wait、notify 方法 多线程练习 单例模式 饿汉模式 懒汉模式 指令重排序 wait、notify 方法 wait 和 我们前面学习的sleep…

MySQL-基础汇总

MySQL-基础汇总 数据库对于任何一个从事后台开发的人说都是永远躲不掉的&#xff0c;任何系统或程序离开了数据的支持都变的毫无意义。而管理数据的工具——数据库就显得尤为重要。本章节我们的核心就是 MySQL&#xff0c;相信很多小伙伴跟我一样&#xff0c;也沉浸在增、删、…

【AD】1-2 AD24软件的中英文版本切换

1.如图设置软件后&#xff0c;关闭软件重新打开。如果想要切换回英文&#xff0c;将③勾选去掉&#xff0c;关闭软件重新在打开即可。

CSS、Less、Scss

CSS、Less和SCSS都是用于描述网页外观的样式表语言&#xff0c;但它们各自具有不同的特点和功能。以下是对这三者的详细阐述及区别对比&#xff1a; 详细阐述 CSS&#xff08;Cascading Style Sheets&#xff09; 定义&#xff1a;CSS是一种用来表现HTML或XML等文件样式的计算机…

【Python项目管理】“无法创建虚拟环境”报错原因及解决方法

一、问题说明 笔者最近在做一个python项目&#xff08;使用pycharm IDE&#xff09;&#xff0c;在添加python解释器时&#xff0c;提示无法创建虚拟环境&#xff08;Unable to create virtual environment&#xff09;&#xff0c;如下2图所示&#xff1a; 【添加python解释…

【实践】某央企研究院如何打造IT监控告警平台?

01客户简介&#xff1a; 案例客户为某央企下属研究院。 02痛点分析&#xff1a; 随着信创国产化持续推进&#xff0c;案例客户已完成部分IT核心系统的替代&#xff0c;部署了一系列国产软硬件设施&#xff0c;如Kylinv10操作系统、融智通网络设备等。由于信创生态不够成熟&a…

qt QBrush详解

1、概述 QBrush是Qt框架中的一个基本图形对象类&#xff0c;它主要用于定义图形的填充模式。QBrush可以用于填充如矩形、椭圆形、多边形等形状&#xff0c;也可以用于绘制背景等。通过QBrush&#xff0c;可以设置填充的颜色、样式&#xff08;如实心、渐变、纹理等&#xff09…

0-1规划的求解

实验类型&#xff1a;◆验证性实验 ◇综合性实验 ◇设计性实验 实验目的&#xff1a;学会使用Matlab编程实现求解0-1规划。 实验内容&#xff1a;1.学习使用Matlab定义子函数的命令function&#xff1b; 2.编程求解0-1型整数规划的枚举法或隐枚举法。 例1&#xff1a;求…

禾川HCQ1控制器程序编译报错如何解决

1、第一次打开用户程序 2、提示库未安装 3、安装库文件 4、脉冲轴库未安装 5、没有错误 去禾川自动化官网,把可以安装的包和库都安装下,程序编译就没有错误了。 6、下载相关包文件