240422 leetcode exercises
240422 leetcode exercises
@jarringslee
文章目录
- 240422 leetcode exercises
- [237. 删除链表中的节点](https://leetcode.cn/problems/delete-node-in-a-linked-list/)
- 🔁节点覆盖法
- [392. 判断子序列](https://leetcode.cn/problems/is-subsequence/)
- 🔁直接遍历
- 🔁动归预处理
- [LCR 136. 删除链表的节点](https://leetcode.cn/problems/shan-chu-lian-biao-de-jie-dian-lcof/)
- 🔁直接遍历
237. 删除链表中的节点
有一个单链表的
head,我们想删除它其中的一个节点node。给你一个需要删除的节点
node。你将 无法访问 第一个节点head。链表的所有值都是 唯一的,并且保证给定的节点
node不是链表中的最后一个节点。删除给定的节点。注意,删除节点并不是指从内存中删除它。这里的意思是:
- 给定节点的值不应该存在于链表中。
- 链表中的节点数应该减少 1。
node前面的所有值顺序相同。node后面的所有值顺序相同。
他是想说什么意思呢,就是在不给你整个链表的情况下,让你根据这个值来将这个节点删除。
题目要求我们的函数被调用后输出整个链表,而我们又注意到所写函数是void类型,所以我们只需要执行删除该节点的操作即可。
如果毫无思路,我们可以回忆一下删除链表的原理:
让上一个结点的next指针直接指向下一个节点。
由于我们需要对链表进行遍历,才能获得前驱指针并执行上述操作。但是这里我们根本无法获取前驱指针。但是我们写的函数又不需要我们返回链表,所以如果让当前节点的值直接变成下一结点的值,也就是覆盖下一个节点,是不是就等价于删除了当前节点呢?
🔁节点覆盖法
假设链表在内存中是这样的(箭头表示 next 指针):
→ [ A | * ] → [ B | * ] → [ C | * ] → …↑题目给出的node
[A|*]表示当前节点的val = A,next指向下一个节点。node指针正指向值为A的节点,我们删掉它。
void deleteNode(struct ListNode* node) {*node = *node -> next; //哈哈就一行。
}
这一行等价于同时做了两件事:
node->val = node->next->val; // 把后继节点的值 B 复制到当前节点
node->next = node->next->next; // 把后继节点的 next 指针复制过来
我们看看这个操作带来了什么样的影响:
-
操作前
[ A | -> X ] [ B | -> Y ]node next_nodenode->val = Anode->next指向下一个节点(值 B)
-
执行
*node = *node->next;node->val变成了Bnode->next变成了node->next->next(即原来 B 的 next,指向 C)
-
操作后
[ B | -> Y ] [ B | -> Y ] node (原 B 节点,已被孤立)现在的链表里,从
…→node开始… → [ B | * ] → [ C | * ] → …——等价于把原来的 B 节点直接「搬到」A 的位置,然后把原 B 节点从链表里跳过去了。
这道题通过 复制后继节点 到当前节点,再跳过后继,实现了在不知道前驱的情况下删除节点的目标。关键一句 *node = *node->next;,相当于同时做了赋值 val 和重连 next,从链表逻辑上删掉了下一节点。
我简直是天才。
392. 判断子序列
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,
"ace"是"abcde"的一个子序列,而"aec"不是)。进阶:
如果有大量输入的 S,称作 S1, S2, … , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?
示例 1:
输入:s = "abc", t = "ahbgdc" 输出:true示例 2:
输入:s = "axc", t = "ahbgdc" 输出:false
乍一看以为是包含字符串的问题,结果仔细一看,发现如果子序列的所有字符能被给出序列顺序地包含就符合条件。那么单次遍历的话就会简单很多。
🔁直接遍历
直接建立循环直接进行比较。
bool isSubsequence(char* s, char* t) {if (s[0] == '\0') return true;//排除空字符串情况int i = 0;for (int j = 0; t[j] != '\0'; j++){ //外循环移动大串if (s[i] == t[j]) i++;//如果发现该位置与小串相等,小串移动if (s[i] == '\0') return true;//循环内移动完了就成功}return false;
}
但是题目又说, “当 t 很长、要对它执行大量(10亿)子序列判断查询”,在这种变态情况下,我们想刚才那样愚蠢地遍历好像是有点笨拙了。但倘若我预处理目标串 t,一次性记录好从每个位置往后字符 a…z 下次出现的位置,然后再用这个表快速「跳跃式」地在 t 中定位每个要匹配的 s[j],阁下又该如何应对?
🔁动归预处理
1. What is nxt?
我们使用 (n+1)×26 的二维整型数组,用来存储 “从位置 i 开始,字母 'a'+c 下一次出现的位置”(其中 0 ≤ i ≤ n,0 ≤ c < 26)。
nxt[i][c] 的含义是,在字符串 t 中,从下标 i(包含)往后,第一个字符等于 'a'+c 的位置索引;
如果再也不出现,即t 中再也没有字符 ('a'+c),我们就把它设为 n(一个「越界」值)。
int (*nxt)[SIGMA] = malloc((n + 1) * sizeof(int[SIGMA]));
如果 t 中再也没有字符 ('a'+c),我们就把它设为 n(一个「越界」值)。
这样,查找 “从位置 i 往后,‘x’ 下次出现在哪里” 就只需要读 nxt[i]['x'-'a'] 一次,时间 O(1)。
2. 构造 nxt 表
-
初始化末尾行
for (int j = 0; j < SIGMA; j++) {nxt[n][j] = n; }位置
n之后没有任何字符,所有字母的「下次出现」都标记为n。 -
自底向上填表
for (int i = n - 1; i >= 0; i--) {// 先拷贝后一行:默认后续出现位置和 i+1 一样memcpy(nxt[i], nxt[i + 1], SIGMA * sizeof(int));// 然后把 t[i] 这一个字符的“下次出现”位置修正为 i 自己nxt[i][t[i] - 'a'] = i; }-
“如果我在 i+1 后面第一次见到 c,位置是谁?” →
nxt[i+1][c] -
“但如果
t[i]本身就是 c,就应该最近出现的位置是 i” → 覆盖nxt[i][c] = i -
最终,
nxt[0][c]恰好告诉我们「整个串中第一次出现 c 的位置」。
-
3. 用 nxt 快速匹配子序列
int i = -1;
for (int j = 0; s[j] && i < n; j++) {// 在 t 中,从 i+1 开始,寻找 s[j] 下一个出现的位置i = nxt[i + 1][s[j] - 'a'];
}
return i < n;
我们用 i 记录上一次匹配到 t 的哪个位置。若初始 i = -1,表示还没匹配过任何字符;要找下一个,就从 i+1 = 0 开始搜。对于对每个 s[j],我们先计算 c = s[j]-'a',再读 pos = nxt[i+1][c]。
如果 pos < n,说明在 t 中找到了,就把 i = pos,继续下一个 s[j+1]。
如果 pos == n,说明找不到,就会让 i >= n ,循环后自然跳出,最后 return false。
整个过程只做了 |s| 步 O(1) 的跳跃查询,匹配结束后检查 i < n 即可判断 s 是否完全匹配为子序列。
时间和空间复杂度
- 预处理
- 时间:构造
nxt需要做n+1行,每行拷贝 26 个整数 → O(26·n) ≈ O(n)。- 空间:存
(n+1)×26个int→ O(n·Σ),这里 Σ=26。- 匹配阶段
- 时间:遍历
s一次,每步 O(1) 查表 → O(|s|)。
对于极多次查询同一个 t 是否包含不同 s 的变态情况,这种预处理 + 跳表的方法尤其高效。
LCR 136. 删除链表的节点
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。
返回删除后的链表的头节点。
示例 1:
输入:head = [4,5,1,9], val = 5 输出:[4,1,9] 解释:给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.示例 2:
输入:head = [4,5,1,9], val = 1 输出:[4,5,9] 解释:给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.
我们使用前去节点遍历的方法来找到需要删除的值。
🔁直接遍历
首先去掉目标只在头结点的情况。
我们让前驱指针在下个节点的指针不指向空和下个节点的值不等于目标值的情况下向前移动,在题目保证数据的情况下,一定会在指针走向尽头之前因为找到目标值而跳出这个循环。这时候我们让前驱指针所在的节点的next指针直接指向下一个节点的next指针,也就是下下一个节点的地址。
struct ListNode* deleteNode(struct ListNode* head, int val) {if (head -> val == val) return head -> next;struct ListNode* prev = head;
//不满足条件就遍历while( (prev -> next != NULL) && (prev -> next -> val != val)) prev = prev -> next;
//找到目标值就删if (prev -> next != NULL) prev -> next = prev -> next -> next; return head;
}
相关文章:
240422 leetcode exercises
240422 leetcode exercises jarringslee 文章目录 240422 leetcode exercises[237. 删除链表中的节点](https://leetcode.cn/problems/delete-node-in-a-linked-list/)🔁节点覆盖法 [392. 判断子序列](https://leetcode.cn/problems/is-subsequence/)🔁…...
mybatis mapper.xml中使用枚举
重点:application.propertis配置类 #TypeEnumHandler 这个类的包名,不是全路径 mybatis.type-handlers-packagecom.fan.test.handler两个枚举类: public enum StatusEnum {DELETED(0),ACTIVE(1);private final int code;StatusEnum(int cod…...
【初级】前端开发工程师面试100题(二)
本题库共计包含100题,考察html,css,js,以及react,vue,webpack等基础知识掌握情况。 TypeScript篇 TypeScript和JavaScript有什么区别? TS是JS的超集,添加了静态类型系统,编译时检查类型错误,适合大型项目。interface和type有什么区别? interface主要用于描述对象形…...
Appium安装 -- app笔记
调试环境:JDK(java) SDK(android) Node.js 雷神模拟器(或 真机) Appium(Appium Server【内外件(dos内件、界面化工具)】、Appium Inspector) p…...
2025.04.23华为机考第一题-100分
📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围OJ 01. 星空探索者 问题描述 LYA是一位天文学爱好者,她拍摄了一张星空照片并将其数字化为二维亮度图。在这张图像中,每个像素点的值代表该位置的亮度。现在,LYA想要寻找特定亮度的星…...
【OpenGL】OpenGL学习笔记-1:VS2019配置OpenGL开发环境
在Visual Studio 2019中可以通过手动配置库文件或NuGet包管理器快速安装的方法配置OpenGL环境,详细步骤如下: 一、打开VS2019,创建新的控制台项目 二、方法一:手动配置GLEW/GLFW/GLAD库 GLFW是窗口管理和输入事件的基础设施&…...
集结号海螺捕鱼游戏源码解析(第二篇):水浒传捕鱼模块逻辑与服务器帧同步详解
本篇将全面解构“水浒传”子游戏的服务端核心逻辑、帧同步机制、鱼群刷新规则、客户端命中表现与服务器计算之间的协同方式,聚焦于 C 与 Unity3D 跨端同步的真实实现过程。 一、水浒传捕鱼模块资源结构 该模块包含三部分核心目录: 子游戏/game_shuihuz…...
从零到一实现 .NET Core 项目 + JWT 认证
知识文档:从零到一实现 .NET Core 项目 + JWT 认证 1. 知识点概述 本项目通过实现 JWT 身份验证,完成以下功能: 用户登录并生成 JWT Token。使用 [Authorize] 属性保护受控资源。测试登录和受保护资源访问的完整流程。JWT(JSON Web Token)是一种轻量级的认证机制,广泛用…...
【音视频】FFmpeg内存模型
FFmpeg内存模型 从现有的Packet拷贝一个新Packet的时候,有两种情况: 两个Packet的buf引用的是同一数据缓存空间,这时候要注意数据缓存空间的释放问题;两个Packet的buf引用不同的数据缓存空间,每个Packet都有数据缓存…...
QML 样式库
在 QML 中,样式库(或 UI 框架)用于快速构建一致且美观的界面。Qt/QML 本身不提供内置的完整样式库,但可以通过以下方式实现样式管理或使用第三方库。 1. Qt Quick Controls 2 样式系统 Qt Quick Controls 2 是官方提供的 UI 组件…...
小白自学python第一天
学习python的第一天 一、常用的值类型(先来粗略认识一下~) 类型说明数字(number)包含整型(int)、浮点型(float)、复数(complex)、布尔(boolean&…...
2022 年 9 月青少年软编等考 C 语言七级真题解析
目录 T1. 二叉树的深度T2. 迷宫思路分析T3. Sequence思路分析T4. Priority Queue 练习题思路分析T1. 二叉树的深度 题目链接:SOJ D1164 此题为 2022 年 3 月七级第三题原题,见 2022 年 3 月青少年软编等考 C 语言七级真题解析中的 T3。 T2. 迷宫 题目链接:SOJ D1213 一…...
手动实现LinkedList
前言 大家好,我是Maybe。最近在学习数据结构中的链表,自己手动实现了一个LinkedList。我想与大家分享一下。 思维导图 代码部分 package Constant;public class constant {public static final String INDEX_IS_WRONG"输入的下标不合法"; }p…...
maven的安装与配置、IDEA集成maven
一、maven的安装与配置环境变量 maven的下载与安装,配置环境变量与验证【附安装包3.6.1,3.8.8,3.9.9】-CSDN博客 参考资料:黑马程序员 二、IDEA集成 2.1 当前工程设置 1. 打开 Maven 设置路径:在 IDEA 中…...
Axure中继器表格:实现复杂交互设计的利器
在产品原型设计领域,Axure凭借其强大的元件库和交互功能,成为设计师们手中的得力工具。其中,中继器元件在表格设计方面展现出了独特的优势,结合动态面板等元件,能够打造出功能丰富、交互体验良好的表格原型。本文将深入…...
VR 全景看车的独特优势
全方位沉浸式体验 VR 全景看车最显著的优势,就是为用户带来了全方位的沉浸式体验。通过 VR 技术,用户仿佛置身于真实的汽车展厅或试驾场景之中,能够 360 度无死角地观察车辆的外观、内饰、细节等各个方面 。无论是车辆的整体造型࿰…...
前端 JavaScript 处理流式响应的坑
给使用 JavaScript 的同学提个醒! 浏览器端处理流式响应,想要完美体验 请使用 Fetch API。 Axios 无法使用stream来直接处理真正的流式响应(但 Node.js 中可以使用 stream),这与浏览器底层 HTTP 请求实现的限制有关。 …...
AI Agent认知框架(ReAct、函数调用、计划与执行、自问自答、批判修正、思维链、思维树详解和对比,最后表格整理总结
以下是主流AI Agent认知框架的详细说明、对比及表格总结: 1. 各认知框架详解 (1) ReAct (Reasoning Action) 定义:结合推理(Reasoning)和行动(Action)的循环过程。核心机制: 模型先推理&…...
springBoot_自定义starter
Spring Boot 自定义 Starter 详解 一、Spring Boot Starter 基础概念 1.1 什么是 Spring Boot Starter Spring Boot Starter 是 Spring Boot 的一个核心概念,它是一种特殊的依赖描述符,包含了一组可以集成到应用中的依赖项。简单来说,Star…...
搭建TypeScript单元测试环境
我们在学习TypeScript的时候如果能够搭建一个单元测试的环境,那写些demo会很简单,下面我们使用jest来搭建一个单元测试环境 Jest 是一个由 Facebook 开发并开源的 JavaScript 测试框架,被广泛应用于前端和 Node.js 项目的单元测试。以下是关…...
第十一届机械工程、材料和自动化技术国际会议(MMEAT 2025)
重要信息 官网:www.mmeat.net 时间:2025年06月23-25日 地点:中国-深圳 部分展示 征稿主题 智能制造和工业自动化 复合材料与高性能材料先进制造技术 自动化机器人系统 云制造与物联网集成 精密制造技术 智能生产线优化 实时数据分析与过…...
leetcode 1143. Longest Common Subsequence
目录 题目描述 第一步,明确并理解dp数组及下标的含义 第二步,分析明确并理解递推公式 第三步,理解dp数组如何初始化 第四步,理解遍历顺序 代码 题目描述 这道题和第718题的区别就是,本题求的是最长公共子序列的长…...
SSH 私钥文件权限控制指南
1. 为什么必须严格控制私钥文件权限? 安全机制:SSH 协议强制要求私钥文件必须仅对所有者可读,防止未授权访问。 风险:若权限过松(如其他用户可读),SSH 客户端会拒绝连接,避免私钥泄…...
stack和queue的学习
stack的介绍 stack的文档介绍 stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,…...
微服务Nacos组件的介绍、安装、使用
微服务Nacos组件的介绍、安装、使用 在微服务架构日渐普及的今天,服务注册与配置管理成了系统架构中的关键环节。阿里巴巴开源的 Nacos(Naming and Configuration Service)正是解决这一问题的利器。本文将为你全面介绍 Nacos 的概念、安装方…...
SpringBoot_为何需要SpringBoot?
Spring Boot 出现前的开发困境 配置繁琐 大量的 XML 配置文件 Spring 是一个非常优秀的轻量级框架,但其配置却是重量级的需要编写大量的 XML 配置文件或注解配置,使项目配置复杂且难以维护配置文件中容易出现错误,且排查问题困难开发过程中…...
格式工厂 v5.18最新免安装绿色便携版
前言 用它来转视频的时候,还能顺便给那些有点小瑕疵的视频修修补补,保证转出来的视频质量杠杠的。更厉害的是,它不只是转换那么简单,还能帮你把PDF合并成一本小册子,视频也能合并成大片,还能随心所欲地裁剪…...
使用logrotate实现日志轮转
logrotate 是一个强大的 Linux 工具,用于自动化管理日志文件的轮转、压缩、删除和归档。它能有效防止日志文件无限增长,节省磁盘空间,同时保持日志的可追溯性。以下是详细讲解 logrotate 的用法,涵盖安装、配置、测试、自动化、常…...
MQTTX + MCP:MQTT 客户端秒变物联网 Agent
引言:MQTTX 与 MCP 的融合 作为最受欢迎的 MQTT 客户端工具,MQTTX 在 1.12.0 beta 版本中集成了模型上下文协议(MCP)到 Copilot AI 功能中,显著提升了服务能力。这一融合让 MQTTX 转变为 MCP Host(也就是发…...
redis close+连接参数设置+并发情况风险分析
1,如下代码 redis 为什么 client.close,不关闭会出现什么问题 public void confirm(String token, MenuHistoryVO menuHistoryVO) {if (StringUtil.isEmptyOrNull(token) || Objects.isNull(menuHistoryVO)) {return;}String key getKey(token);JedisC…...
