LeetCode 热题 100 | 链表(下)
目录
1 148. 排序链表
2 23. 合并 K 个升序链表
3 146. LRU 缓存
3.1 解题思路
3.2 详细过程
3.3 完整代码
菜鸟做题第三周,语言是 C++
1 148. 排序链表
解题思路:
- 遍历链表,把每个节点的 val 都存入数组中
- 用 sort 函数对数组进行排序
- 遍历链表,更新每个节点的 val
class Solution {
public:ListNode* sortList(ListNode* head) {ListNode * p = head;vector<int> vals;while (p) {vals.push_back(p->val);p = p->next;}sort(vals.begin(), vals.end());p = head;int i = 0;while (p) {p->val = vals[i];p = p->next;++i;}return head;}
};
2 23. 合并 K 个升序链表
解题思路:
- 遍历所有链表,把每个节点的 val 都存入数组中
- 用 sort 函数对数组进行排序
- 构造新的链表,并放入数组中的值
class Solution {
public:ListNode* mergeKLists(vector<ListNode*>& lists) {vector<int> vals;int n = lists.size();if (n == 0) return nullptr;for (int i = 0; i < n; ++i) {ListNode * p = lists[i];while (p) {vals.push_back(p->val);p = p->next;}}sort(vals.begin(), vals.end());ListNode * dummy = new ListNode(0);ListNode * p = dummy;for (auto &val:vals) {ListNode * t = new ListNode(val);p->next = t;p = t;}return dummy->next;}
};
3 146. LRU 缓存
3.1 解题思路
- 构造双向链表,用于表示某节点最近是否被使用
- 构造哈希表,用于快速定位节点位置
Q:如何表示某节点最近是否被访问?
A:在我的解法中,将最近被使用的节点链在链表尾部。由此,越靠近头部的节点越少被使用。
Q:什么叫被使用?
A:被使用包含两种:最新被插入到链表中的节点、最新被访问的节点。
Q:为什么一定要构造双向链表?
A:哈希表中存储的是节点的地址,帮助我们快速定位。但是定位只能定位到节点本身,而不能定位到节点的前一个节点,因此使用单向链表将无法完成节点的删除。
3.2 详细过程
① 定义双向链表结构体
struct DListNode {int key, value;DListNode * prev, * next;DListNode() : key(0), value(0), prev(nullptr), next(nullptr) {}DListNode(int x, int y) : key(x), value(y), prev(nullptr), next(nullptr) {}
};
照抄力扣定义的结构体即可,只不过多了一个 prev 前向指针。
② 定义变量
int cap = 0, size = 0;
unordered_map<int, DListNode *> hashtable;
DListNode * head, * tail;
- cap 表示缓存的容量,size 表示缓存目前被占用的量
- hashtable 的键是节点的 key,值是节点的地址 DListNode *
- head 和 tail 是虚拟节点,辅助节点的插入和删除
③ 定义函数
void addToTail(int key, int value) {DListNode * node = new DListNode(key, value);hashtable[key] = node;node->next = tail;node->prev = tail->prev;tail->prev->next = node;tail->prev = node;++size;
}void moveToTail(int key) {DListNode * node = hashtable[key];node->prev->next = node->next;node->next->prev = node->prev;--size;addToTail(key, hashtable[key]->value);
}void delHeadNode() {DListNode * node = head->next;node->next->prev = head;head->next = node->next;delete node;
}
- addToTail:是指在链尾插入新的节点
- moveToTail:是指将最近使用到的节点删除,再插入到链尾
- delHeadNode:是指缓存空间不够时,删除头节点
由于在我的解法中 “越靠近头部的节点越少被使用”,所以每次被替换掉的是头节点。
3.3 完整代码
class LRUCache {
public:struct DListNode {int key, value;DListNode * prev, * next;DListNode() : key(0), value(0), prev(nullptr), next(nullptr) {}DListNode(int x, int y) : key(x), value(y), prev(nullptr), next(nullptr) {}};int cap = 0, size = 0;unordered_map<int, DListNode *> hashtable;DListNode * head, * tail;LRUCache(int capacity) {cap = capacity;head = new DListNode();tail = new DListNode();head->next = tail;tail->prev = head;}int get(int key) {if (hashtable.count(key)) {moveToTail(key);return hashtable[key]->value;}return -1;}void put(int key, int value) {if (hashtable.count(key)) {hashtable[key]->value = value;moveToTail(key);} else if (!hashtable.count(key)) {if (size < cap) {addToTail(key, value);} else if (size >= cap) {hashtable.erase(head->next->key);delHeadNode();addToTail(key, value);}}}void addToTail(int key, int value) {DListNode * node = new DListNode(key, value);hashtable[key] = node;node->next = tail;node->prev = tail->prev;tail->prev->next = node;tail->prev = node;++size;}void moveToTail(int key) {DListNode * node = hashtable[key];node->prev->next = node->next;node->next->prev = node->prev;--size;addToTail(key, hashtable[key]->value);}void delHeadNode() {DListNode * node = head->next;node->next->prev = head;head->next = node->next;delete node;}
};
相关文章:
LeetCode 热题 100 | 链表(下)
目录 1 148. 排序链表 2 23. 合并 K 个升序链表 3 146. LRU 缓存 3.1 解题思路 3.2 详细过程 3.3 完整代码 菜鸟做题第三周,语言是 C 1 148. 排序链表 解题思路: 遍历链表,把每个节点的 val 都存入数组中用 sort 函数对数组进…...
Ubuntu搭建计算集群
计算机硬件和技术的发展使得高性能模拟和计算在生活和工作中的作用逐渐显现出来,无论是计算化学,计算物理和当下的人工智能都离不开高性能计算。笔者工作主要围绕计算化学和物理开展,亦受限于自身知识和技术所限,文中只是浅显地尝…...
数据结构~~树(2024/2/8)
目录 树 1、定义: 2、树的基本术语: 3、树的表示 树 1、定义: 树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&…...
【教学类-48-03】202402011“闰年”(每4年一次 2月有29日)世纪年必须整除400才是闰年)
2000-2099年之间的闰年有25次, 背景需求: 已经制作了对称年月的数字提取,和年月日相等的年份提取 【教学类-48-01】20240205对称的“年”和“月日”(如2030 0302)-CSDN博客文章浏览阅读84次。【教学类-48-01】202402…...
如何开发一个属于自己的人工智能语言大模型?
要开发一个属于自己的人工智能语言模型,你需要遵循以下步骤: 数据收集:首先你需要大量的文本数据来训练你的模型。这些数据可以来自于各种来源,例如书籍、网站、新闻文章等。你需要确保这些数据足够多样化,以便模型能学…...
【HTTP】localhost和127.0.0.1的区别是什么?
目录 localhost是什么呢? 从域名到程序 localhost和127.0.0.1的区别是什么? 域名的等级划分 多网站共用一个IP和端口 私有IP地址 IPv6 今天在网上逛的时候看到一个问题,没想到大家讨论的很热烈,就是标题中这个: …...
Edge浏览器-常用快捷键
按键组合作用Ctrl Shift I开发人员工具Ctrl E定位到 空地址栏Ctrl L定位到 地址栏Ctrl Shift B显示或隐藏 收藏夹栏Ctrl Shift O打开收藏夹(搜索)Ctrl T打开一个新标签页Ctrl W关闭当前标签页Ctrl Shift T重新打开刚才关闭的标签页Ctrl Tab切换到下一个标签页Ctrl…...
C++:Vector动态数组的copy深入理解
动态数组分配的大小默认为2的n次方1,2,4,8... 在main中创建的vertices,push需要放到Vertex中(copy),下一次copy是因为要调整vertices的大小 vertices.push_back(Vertex(1,2,3));//拷贝 第一次&a…...
【PyTorch】PyTorch中张量(Tensor)切片操作
PyTorch深度学习总结 第三章 PyTorch中张量(Tensor)切片操作 文章目录 PyTorch深度学习总结一、前言二、获取张量中的元素1、切片(行、列数)方法2、torch.where()函数3、使元素置零的操作 一、前言 上文介绍了PyTorch中改变张量(Tensor)形状的操作&…...
GeoServer 2.11.1升级解决Eclipse Jetty 的一系列安全漏洞问题
Eclipse Jetty 资源管理错误漏洞(CVE-2021-28165) Eclipse Jetty HTTP请求走私漏洞(CVE-2017-7656) Eclipse Jetty HTTP请求走私漏洞(CVE-2017-7657) Eclipse Jetty HTTP请求走私漏洞(CVE-2017-7658) Jetty 信息泄露漏洞(CVE-2017-9735) Eclipse Jetty 安全漏洞(CVE-2022-20…...
【蓝桥杯选拔赛真题34】C++最大值 第十三届蓝桥杯青少年创意编程大赛C++编程选拔赛真题解析
目录 C/C++最大值 一、题目要求 1、编程实现 2、输入输出...
STM32之USART
概述 串口通信,通用异步收发传输器(Universal Asynchronous Receiver/Transmitter ),简称UART;而USART(Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步收发传输器。 USAR…...
unity 点击事件
目录 点击按钮,显示图片功能教程 第1步添加ui button,添加ui RawImage 第2步 添加脚本: 第3步,把脚本拖拽到button,点击button,设置脚本的变量, GameObject添加 Component组件 点击按钮&am…...
idea自带的HttpClient使用
1. 全局变量配置 {"local":{"baseUrl": "http://localhost:9001/"},"test": {"baseUrl": "http://localhost:9002/"} }2. 登录并将结果设置到全局变量 PostMapping("/login")public JSONObject login(H…...
vue3-应用规模化-路由和状态
客户端 vs. 服务端路由 服务端路由指的是服务器根据用户访问的 URL 路径返回不同的响应结果。当我们在一个传统的服务端渲染的 web 应用中点击一个链接时,浏览器会从服务端获得全新的 HTML,然后重新加载整个页面。 然而,在单页面应用中&…...
网络安全检查表
《网络攻击检查表》 1.应用安全漏洞 2.弱口令,默认口令 3.服务器互联网暴露 4.操作系统,中间件安全漏洞 5.研发服务器,邮件服务器等安全检查...
SSM框架,Maven的学习(下)
依赖传递和依赖冲突 依赖传递指的是当一个模块或库 A 依赖于另一个模块或库 B,而 B 又依赖于模块或库 C,那么 A 会间接依赖于 C。这种依赖传递结构可以形成一个依赖树。当我们引入一个库或框架时,构建工具(如 Maven、Gradle&…...
Vivado开发FPGA使用流程、教程 verilog(建立工程、编译文件到最终烧录的全流程)
目录 一、概述 二、工程创建 三、添加设计文件并编译 四、线上仿真 五、布局布线 六、生成比特流文件 七、烧录 一、概述 vivado开发FPGA流程分为创建工程、添加设计文件、编译、线上仿真、布局布线(添加约束文件)、生成比特流文件、烧录等步骤&a…...
C语言之动态内存管理
目录 1. 为什么要有动态内存分配2. malloc和freemallocfree 3. calloc和realloccallocrealloc 4. 常见的动态内存的错误对NULL直接的解引用操作对动态开辟空间的越界访问对非动态开辟内存使用free释放使用free释放一块动态开辟内存的一部分对同一块动态内存多次释放动态开辟内存…...
【AIGC风格prompt深度指南】掌握绘画风格关键词,实现艺术模仿的革新实践
[小提琴家]ASCII风格,点,爆炸,光,射线,计算机代码 由冰和水制成的和平标志]非常详细,寒冷,冰冻,大气,照片逼真,流动,16K 胡迪尼模拟火和水&#x…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
