当前位置: 首页 > news >正文

二、链表(linked-list)

文章目录

  • 一、定义
  • 二、经典例题
    • (一)[21.合并两个有序链表](https://leetcode.cn/problems/merge-two-sorted-lists/description/)
      • 1.思路
      • 2.复杂度分析
      • 3.注意
      • 4.代码
    • (二)[86.分割链表](https://leetcode.cn/problems/partition-list/description/)
      • 1.思路
      • 2.复杂度分析
      • 3.代码
    • (三)[23.合并 K 个升序链表](https://leetcode.cn/problems/merge-k-sorted-lists/description/)
      • 1.思路
      • 2.复杂度分析
      • 3.代码
    • (四)[19.删除链表中的倒数第N个节点](https://leetcode.cn/problems/remove-nth-node-from-end-of-list/)
      • 1.思路
      • 2.复杂度分析
      • 3.代码

一、定义

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。

二、经典例题

(一)21.合并两个有序链表

在这里插入图片描述

1.思路

根据题目描述,链表l1, l2是递增的,因此容易想到使用双指针cur1和cur2遍历两链表,根据cur1.val和cur2.val的大小关系确定节点添加顺序,两节点指针交替前进,直至遍历完毕。
同时因为两个链表都是有序的,所以,当我们遍历完一个链表,剩下的那个链表如果没到结尾,可以直接跟上。

2.复杂度分析

时间复杂度 O(M+N) : M,N别为两个链表的长度,合并操作需遍历两链表。
空间复杂度 O(1): 节点引用 dum , cur使用常数大小的额外空间。

3.注意

Dummy节点的作用是作为一个虚拟的头前节点。在不知道要返回的新链表的头结点是哪一个,它可能是原链表的第一个节点,可能在原链表的中间,也可能在最后,甚至不存在(nil)。引入Dummy节点可以涵盖所有情况,并且可以使用dummy.next返回最终需要的头结点。

4.代码

/*** 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* cur1 = list1;ListNode* cur2 = list2;ListNode* dummy = new ListNode(-1); // 虚拟头结点ListNode* cur = dummy;while (cur1 && cur2) {// 比较 p1 和 p2 两个指针// 将值较小的的节点接到 p 指针if (cur1 -> val > cur2 -> val) {cur -> next = cur2;cur2 = cur2 -> next;}else {cur -> next = cur1;cur1 = cur1 -> next;}cur = cur -> next; // p 指针不断前进}if (cur1) cur -> next = cur1;if (cur2) cur -> next = cur2;return dummy -> next;}
};

(二)86.分割链表

1.思路

具体来说,我们可以把原链表分成两个小链表,一个链表中的元素大小都小于 x,另一个链表中的元素都大于等于 x,最后再把这两条链表接到一起,就得到了题目想要的结果。

2.复杂度分析

时间复杂度 O(N): 其中 N为链表长度;遍历链表使用线性时间。

空间复杂度 O(1) : 假头节点使用常数大小的额外空间。

3.代码

/*** 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* partition(ListNode* head, int x) {ListNode* dummy1 = new ListNode(-1);ListNode* dummy2 = new ListNode(-1);ListNode* small = dummy1;ListNode* big = dummy2;// 新建两个链表 small,big,分别用于添加所有节点值<x、节点值>=的节点ListNode* cur = head;while (cur) {if (cur -> val >= x) {big -> next = cur;big = big -> next;}else {small -> next = cur;small = small -> next;}cur = cur -> next;}small -> next = dummy2 -> next; // 拼接 small 和 bigbig -> next = nullptr;return dummy1 -> next;}
};

(三)23.合并 K 个升序链表

1.思路

如何快速得到 k 个节点中的最小节点,接到结果链表上?

  • 这里我们就要用到 优先级队列(二叉堆) 这种数据结构,把链表节点放入一个最小堆,就可以每次获得 k 个节点中的最小节点:

优先队列 pq 中的元素个数最多是 k,所以一次 poll 或者 add 方法的时间复杂度是 O(logk);所有的链表节点都会被加入和弹出 pq,所以算法整体的时间复杂度是 O(Nlogk),其中 k 是链表的条数,N 是这些链表的节点总数。

2.复杂度分析

时间复杂度:考虑优先队列中的元素不超过 k 个,那么插入和删除的时间代价为 O(log⁡k),这里最多有 kn 个点,对于每个点都被插入删除各一次,故总的时间代价即渐进时间复杂度为 O(kn×log⁡k)。
空间复杂度:这里用了优先队列,优先队列中的元素不超过 k个,故渐进空间复杂度为 O(k)。

3.代码

/*** 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:
// 时间复杂度 : O(n ∗ log(k))ListNode* mergeKLists(vector<ListNode*>& lists) {if (lists.size() == 0) return nullptr;ListNode* dummy = new ListNode(-1);ListNode* p = dummy;priority_queue<ListNode*, vector<ListNode*>, function<bool(ListNode*, ListNode*)>> pq([] (ListNode* a, ListNode* b) { return a->val > b->val; });for (auto head : lists) {if (head != nullptr) pq.push(head);}while (!pq.empty()) {ListNode* node = pq.top();pq.pop();p -> next = node;if (node -> next != nullptr)pq.push(node->next);p = p -> next;}return dummy -> next;}
};

(四)19.删除链表中的倒数第N个节点

1.思路

假设链表有 n 个节点,倒数第 k 个节点就是正数第 n - k + 1 个节点。
是的,但是算法题一般只给你一个 ListNode 头结点代表一条单链表,你不能直接得出这条链表的长度 n,而需要先遍历一遍链表算出 n 的值,然后再遍历链表计算第 n - k + 1 个节点。
也就是说,这个解法需要遍历两次链表才能得到出倒数第 k 个节点。

2.复杂度分析

3.代码

/*** 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* removeNthFromEnd(ListNode* head, int n) {if (head == nullptr || n == 0) return nullptr;ListNode* dummy = new ListNode(-1);dummy -> next = head;ListNode* x = findFromEnd(dummy, n + 1);x -> next = x -> next -> next;return dummy -> next;}ListNode* findFromEnd(ListNode* head, int k) {// 代码见上文ListNode* slow = head;ListNode* fast = head;while (k -- && fast) {fast = fast -> next;}while (fast) {slow = slow -> next;fast = fast -> next;}return slow;}
};

相关文章:

二、链表(linked-list)

文章目录 一、定义二、经典例题&#xff08;一&#xff09;[21.合并两个有序链表](https://leetcode.cn/problems/merge-two-sorted-lists/description/)1.思路2.复杂度分析3.注意4.代码 &#xff08;二&#xff09;[86.分割链表](https://leetcode.cn/problems/partition-list…...

Android EditText筛选+选择功能开发

在日常开发中经常会遇到这种需求&#xff0c;EditText既需要可以筛选&#xff0c;又可以点击选择。这里筛选功能用的是AutoCompleteTextView&#xff0c;选择功能使用的是第三方库https://github.com/kongzue/DialogX。 Android AutoCompleteTextView(自动完成文本框)的基本使用…...

Linux 信号 alarm函数 setitimer函数

/*#include <unistd.h>unsigned int alarm(unsigned int seconds);功能&#xff1a;设置定时器。函数调用&#xff0c;开始倒计时&#xff0c;0的时候给当前的进程发送SIGALARM信号参数&#xff1a;倒计时的时长。。单位&#xff1a;秒 如果参数为0&#xff0c;无效返回…...

自主设计,模拟实现 RabbitMQ - 实现发送方消息确认机制

目录 一、实现发送方消息确认 1.1、需求分析 什么是发送方的消息确认? 如何实现?...

【数据结构】二叉树的·深度优先遍历(前中后序遍历)and·广度优先(层序遍历)

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …...

优彩云采集器下载-免费优彩云采集器下载地址

免费优彩云采集器。您是否曾为了数据采集而感到头疼不已&#xff1f;是否一直在寻找一种能够轻松、高效地获取所需数据的方法&#xff1f;别着急&#xff0c;让我们一起来了解如何通过优彩云采集器解决这些问题&#xff0c;从而让您产生购买的欲望。 免费全自动采集发布批量管理…...

【Python】OJ 常用函数

这里写目录标题 一. math1. 求阶乘 - factorial()2. 绝对值 - fabs() 二. 容器的方法1. reverse() 三. Python 内置函数1. sort() 一. math 需要引入 math 包&#xff1a;import math 1. 求阶乘 - factorial() import math print(math.factorial(5))--------运行结果-------…...

【Vue】上万个字把事件处理讲解的淋漓尽致

hello&#xff0c;我是小索奇&#xff0c;精心制作的Vue系列教程持续更新哈&#xff0c;想要学习&巩固&避坑就一起学习吧~ 事件处理 事件的基本用法 重点内容 使用v-on:xxx缩写xxx绑定事件&#xff0c;其中 xxx 是事件名&#xff08;回顾&#xff1a;v-bind缩写为冒号…...

Remmina中VNC、SSH和RDP的区别

Remmina 可以在 Linux 系统上对远程进行连接。它支持多种远程连接协议&#xff0c;包括 VNC&#xff08;Virtual Network Computing&#xff09;、SSH&#xff08;Secure Shell&#xff09;和 RDP&#xff08;Remote Desktop Protocol&#xff09;。这些协议用于实现不同类型的…...

Spring Boot实现web.xml功能

Spring Boot实现web.xml功能 1. 基于注解实现1.1 组件注册1.2 WebInitParam注解 2. 基于编码实现2.1 Servlet & Filter2.2 Listener 3. 总结 在Spring Boot中&#xff0c;不再需要使用传统的 web.xml 文件来配置web应用的功能&#xff0c;Spring Boot支持通过注解和基于代码…...

陆拾捌- 如何通过数据影响决策(三)

一、如何正确的引导别人&#xff1f; 引导与误导的区别是什么&#xff1f; 看下面这广告图 单看上面大字的结果&#xff0c;感觉好像真的使用过的人均觉得有好处 可如果我们看下面的细字 对111位连续14天食用&#xff08;本产品&#xff09;的燕麦片非重度使用者所做调研… 从…...

VMware 三种网络连接模式

VMware虚拟机的三种网络连接模式&#xff1a;桥接&#xff0c;NAT&#xff0c;仅主机。 网卡vmnet0,vmnet1,vmnet8区别。 在VMware中&#xff0c;虚拟机的网络连接主要是由VMware创建的虚拟交换机负责实现的&#xff0c;VMware可以根据需要创建多个虚拟网络。 VMware的虚拟网…...

Scikit-Learn快速生成分类数据集

假如你学习了新的分类算法并想进一步探索研究、尝试不同的超参数评估模型性能&#xff0c;但问题是你找不到好的数据集用于实验。幸运的是Scikit-Learn 提供的 make_classification() 方法可以创建不同类型的数据集&#xff0c;它可以生成不同类型的数据集&#xff1a;二分类、…...

西门子 S7 协议解析

目录 1 建立连接 2 读数据 3 写数据 1 建立连接 03 00 00 16 11 E0 00 00 00 01 00 C1 02 10 00 C2 02 03 01 C0 01 0A &#xff08;第一次握手报文&#xff09; 03 00 报文头 00 16 数据总长度&#xff1a;22 11 E0 00 00 00 01 00 C1 02 10 00 C2 02 03 01 C0 01 0A 报文结束…...

一、python解题——求序列最长递增

解题代码&#xff1a; import os import sys# 请在此输入您的代码 n int(input()) a list(map(int, input().split())) # 创建一个初始元素全为1的列表&#xff0c;用来存放每个递增序列的长度 b [1 for x in range(0, n)] # 设置num&#xff0c;用来控制b列表的下标 num …...

【Java 基础篇】Java线程:volatile关键字与原子操作详解

在多线程编程中&#xff0c;确保线程之间的可见性和数据一致性是非常重要的。Java中提供了volatile关键字和原子操作机制&#xff0c;用于解决这些问题。本文将深入讨论volatile关键字和原子操作的用法&#xff0c;以及它们在多线程编程中的重要性和注意事项。 volatile关键字…...

992. K 个不同整数的子数组

992. K 个不同整数的子数组 给定一个正整数数组 nums和一个整数 k&#xff0c;返回 nums 中 「好子数组」 的数目。 如果 nums 的某个子数组中不同整数的个数恰好为 k&#xff0c;则称 nums 的这个连续、不一定不同的子数组为 「好子数组 」。 例如&#xff0c;[1,2,3,1,2] 中…...

Vue 使用vue-cli构建SPA项目(超详细)

目录 一、什么是vue-cli 二&#xff0c;构建SPA项目 三、 运行SPA项目 前言&#xff1a; 在我们搭建SPA项目时候&#xff0c;我们必须去检查我们是否搭建好NodeJS环境 cmd窗口输入以下指令&#xff1a;去检查 node -v npm -v 一、什么是vue-cli Vue CLI&#xff08;Vu…...

SpringBoot工程模板

spring脚手架&#xff1a;https://start.spring.io/ <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocati…...

学习SLAM:SLAM进阶(十)暴力更改ROS中的PCL库

话不多说&#xff0c;上活 1.1 为什么要这么做 项目中有依赖。。。。 1.2 安装VTK7.1.1 PCL1.8.0 略 1.3 移植到ROS 删除ROS依赖的vtk6.2和PCL1.8.0的动态链接库&#xff1a; liugongweiubuntu:~$ sudo mv /usr/lib/x86_64-linux-gnu/libvtk* Desktop/lib/ [sudo] password fo…...

js 事件流、事件冒泡、事件捕获、阻止事件的传播

事件流 js 事件的执行过程分为捕获阶段&#xff08;由外层节点传播到内层节点&#xff09;和冒泡阶段&#xff08;由内层节点传播到外层节点&#xff09;&#xff0c;即先执行捕获阶段的代码&#xff0c;后执行冒泡阶段的代码 事件冒泡 js 事件中的代码默认在冒泡阶段执行&…...

一家美国公司被黑,一个拉美国家政务服务瘫痪

政务系统承包商遭勒索攻击&#xff0c;导致哥伦比亚国家政务服务陷入瘫痪。 据报道&#xff0c;9月19日哥伦比亚的多个重要政府部门正在应对一次勒索软件攻击&#xff0c;官员们被迫大幅变更部门运作方式。 哥伦比亚卫生和社会保护部、司法部门、工商监管部门上周宣布&#x…...

c++ QT 十八位时间戳转换

先说一下UTC&#xff1a; 它是协调世界时间&#xff0c;又称世界统一时间、世界标准时间、国际协调时间&#xff0c;简称UTC UTC时间与本地时间关系&#xff1a;UTC 时间差本地时间 如果UTC时间是 2015-05-01 00:00:00 那么北京时间就是 2015-05-01 08:00:00 解释&#xff1a;…...

全国职业技能大赛云计算--高职组赛题卷④(容器云)

全国职业技能大赛云计算--高职组赛题卷④&#xff08;容器云&#xff09; 第二场次题目&#xff1a;容器云平台部署与运维任务1 Docker CE及私有仓库安装任务&#xff08;5分&#xff09;任务2 基于容器的web应用系统部署任务&#xff08;15分&#xff09;任务3 基于容器的持续…...

【TCP】延时应答 与 捎带应答

延时应答 与 捎带应答 一. 延迟应答&#xff08;效率机制&#xff09;二. 捎带应答&#xff08;效率机制&#xff09; 一. 延迟应答&#xff08;效率机制&#xff09; 延时应答&#xff1a;相当于 流量控制 的延伸。 流量控制是 踩下了刹车&#xff0c;是发送方发的不要太快&a…...

URL与URI小结

文章目录 一、URL是什么&#xff1f;URL的一般形式&#xff1a; 二、分类三、URI总结 一、URL是什么&#xff1f; 每条由Web服务器返回的内容都是和它管理的某个文件相关联的&#xff0c;这些文件中的每一个都有一个唯一的名字&#xff0c;叫做URL&#xff08;通用资源定位符&…...

QT--day5

注册 mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include<QPushButton> #include<QLineEdit> #include<QLabel> #include <QMessageBox> #include<QString> #include<QSqlDatabase> …...

在windows和linux上玩转Tensorrt

为避免重复&#xff0c;一些安装内容我直接贴其他大佬的帖子了&#xff0c;我是按照他们的步骤来操作的&#xff0c;趟过一遍&#xff0c;没有问题。 本篇着重在tensort在Cmakelist中如何配置&#xff0c;以及如何配置编译动/静态库&#xff0c;比较基础&#xff0c;也是想做个…...

七天学会C语言-第五天(函数)

1. 调用有参函数 有参函数是一种接受输入参数&#xff08;参数值&#xff09;并执行特定操作的函数。通过向函数传递参数&#xff0c;你可以将数据传递给函数&#xff0c;让函数处理这些数据并返回结果。 例1&#xff1a;编写一程序&#xff0c;要求用户输入4 个数字&#xf…...

340. 至多包含 K 个不同字符的最长子串

340. 至多包含 K 个不同字符的最长子串 vip...

一级域名指向wordpress页面/营销网站制作公司

简介 目的 本文对最新的 Linux-4.19.4 内核源码进行分析&#xff0c;并详细指出内核 IPC 机制中的消息队列的原理。 进程间通信 IPC&#xff08;进程间通信&#xff0c;InterProcess Communication&#xff09;是内核提供的系统中进程间进行通信的一种机制。系统中每个进程的用…...

logo设计 公司 免费/东莞百度推广优化公司

一、概述 本次分析是基于android7.0的源码&#xff0c;主要是介绍如何通过反射来打开蓝牙的网络共享以及互联网的连接。 二、蓝牙的网络共享 1. 网络共享部分源码分析 关于packages/apps/Settings/src/com/android/settings/TetherSettings.java这个路径的代码是展示设置中…...

创意家居网站建设与管理/网店推广策划方案

css div 底部对齐The bottom property in CSS is useful to change the vertical position of the positioned element. This property has no effects on non-positioned elements. CSS中的bottom属性对于更改已定位元素的垂直位置很有用。 此属性对未定位的元素没有影响。 B…...

兴扬汽车网站谁做的/论坛推广

java生成6位随机数, 全是数字 // 生成6位随机数字 int random6 (int) ((Math.random() * 9 1) * 100000); // 生成5位随机数字 int random5 (int) ((Math.random() * 9 1) * 10000); // 生成4位随机数字 int random4 (int) ((Math.random() * 9 1) * 1000); // 生成3…...

免费房地产网站模板/宁波seo公司排名榜

参考文章:http://blog.csdn.net/mythma/archive/2008/08/31/2857664.aspx 作者:力为http://blog.csdn.net/kamaliang/archive/2009/08/30/4499488.aspx 作者:evilshadow1. 点击【开始】->【运行】 命令&#xff1a;regedit.2. 定位到HKEY_LOCALMACHINE -> SOFTWARE ->…...

个人门户网站建设流程/培训机构查询网

看到渣浪的查看文章或者查看大图有个效果&#xff1a;弹窗查看内容时&#xff0c;如果内容过长有滚动条&#xff0c;则滚动条会被放到body区滚动 什么意思呢&#xff1f; 看个图片&#xff0c;一般正常弹窗是有宽高限制的&#xff0c;如果内容过长则直接在弹窗中进行滚动 点我预…...