【leetcode题解】链表
目录
链表
两数相加
两两交换链表中的节点
重排链表
合并 K 个升序链表(困难)
K 个一组翻转链表
链表
1. 常用技巧
- 画图!!!(直观+形象,便于我们理解)
- 引入虚拟“头”节点(便于处理边界情况;方便我们对链表进行操作)
- 不要吝啬空间,大胆去定义变量
- 快慢双指针(判环;找链表中环的入口;找链表中倒数第n个节点)
2. 链表中的常用操作
- 创建一个新节点 new
- 尾插
- 头插(逆序链表)
两数相加
2. 两数相加 - 力扣(LeetCode)
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {ListNode cur1 = l1, cur2 = l2;ListNode newHead = new ListNode(0);// 创建一个虚拟头节点,方便记录结果ListNode prev = newHead;// 尾插操作的尾指针int t = 0;// 记录进位while (cur1 != null || cur2 != null || t != 0) {// 先加上第一个链表if (cur1 != null) {t += cur1.val;cur1 = cur1.next;}// 再加上第二个链表if (cur2 != null) {t += cur2.val;cur2 = cur2.next;}prev.next = new ListNode(t % 10);prev = prev.next;t /= 10;}return newHead.next;//}
}
两两交换链表中的节点
24. 两两交换链表中的节点 - 力扣(LeetCode)
解法一:递归
解法二:循环、迭代(模拟)
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode swapPairs(ListNode head) {if (head == null || head.next == null)// 空链表或只有一个结点的链表return head;ListNode newhead = new ListNode(0);// 虚拟“头”节点newhead.next = head;ListNode prev = newhead, cur = prev.next, next = cur.next, nnext = next.next;while (cur != null && next != null) {// 1. 交换节点prev.next = next;next.next = cur;cur.next = nnext;// 2. 修改指针prev = cur;// 注意顺序cur = nnext;if (cur != null)next = cur.next;if (next != null)nnext = next.next;}return newhead.next;}
}
重排链表
143. 重排链表 - 力扣(LeetCode)
解法:模拟
1. 找到链表的中间节点(快慢双指针)
2. 把后面的部分逆序(反转链表:双指针;头插法)
3. 合并两个链表(双指针)
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public void reorderList(ListNode head) {// 处理边界情况if (head == null || head.next == null || head.next.next == null)return;// 找链表的中间节点ListNode fast = head, slow = head;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;}// 此时,slow指向中间节点// 2. 把slow后面的部分逆序 - 头插法ListNode newhead = new ListNode(0);// 虚拟头节点ListNode cur = slow.next;//ListNode prev = null;slow.next = null;// 把两个链表分离while (cur != null) {ListNode next = cur.next;// 保存下一个节点cur.next = newhead.next;newhead.next = cur;cur = next;}// 3. 合并两个链表 - 双指针ListNode cur1 = head, cur2 = newhead.next;ListNode ret = new ListNode(0);prev = ret;while (cur1 != null) {// 先放第一个链表prev.next = cur1;prev = cur1;cur1 = cur1.next;// 合并第二个链表if (cur2 != null) {prev.next = cur2;prev = cur2;cur2 = cur2.next;}}}
}
合并 K 个升序链表(困难)
23. 合并 K 个升序链表 - 力扣(LeetCode)
解法一:暴力解法(不推荐)
解法二:利用优先级队列做优化
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode mergeKLists(ListNode[] lists) {// 创建一个小根堆PriorityQueue<ListNode> heap = new PriorityQueue<>((v1, v2) -> v1.val - v2.val);// 把所有的头节点放进小根堆for (ListNode head : lists) {if (head != null)heap.offer(head);}// 合并链表ListNode ret = new ListNode(0);ListNode prev = ret;while (!heap.isEmpty()) {ListNode t = heap.poll();prev.next = t;prev = t;if (t.next != null)heap.offer(t.next);}return ret.next;}
}
解法三:分治 - 递归
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode mergeKLists(ListNode[] lists) {return merge(lists, 0, lists.length - 1);}public ListNode merge(ListNode[] lists, int left, int right) {if (left > right)return null;if (left == right)return lists[left];// 平分数组int mid = (left + right) / 2;// [left,mid] [mid+1,right]// 处理左右两部分ListNode l1 = merge(lists, left, mid);ListNode l2 = merge(lists, mid + 1, right);return mergeTwo(l1, l2);}public ListNode mergeTwo(ListNode l1, ListNode l2) {// 合并两个链表if (l1 == null)return l2;if (l2 == null)return l1;ListNode head = new ListNode(0);ListNode cur1 = l1, cur2 = l2, prev = head;while (cur1 != null && cur2 != null) {if (cur1.val < cur2.val) {//prev.next = cur1;prev = cur1;cur1 = cur1.next;} else {prev.next = cur2;prev = cur2;cur2 = cur2.next;}}if (cur1 != null)prev.next = cur1;if (cur2 != null)prev.next = cur2;return head.next;}
}
K 个一组翻转链表
25. K 个一组翻转链表 - 力扣(LeetCode)
解法:模拟
- 先求出需要逆序多少组:n
- 重复n次,长度为k的链表的逆序即可(头插法)
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode reverseKGroup(ListNode head, int k) {// 1. 先求出需要逆序多少组int n = 0;ListNode cur = head;while (cur != null) {cur = cur.next;n++;}n /= k;// 2. 重复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;}
}相关文章:
【leetcode题解】链表
目录 链表 两数相加 两两交换链表中的节点 重排链表 合并 K 个升序链表(困难) K 个一组翻转链表 链表 1. 常用技巧 画图!!!(直观形象,便于我们理解)引入虚拟“头”节点…...
本地部署Dify 添加Ollama模型DeepSeek
1、准备工作 本地ollama 加载DeepSeek。 安装并登录Dify。 2、添加Ollama模型服务商 在设置-》模型服务上里添加Ollama模型服务商,也叫插件。 3、添加DeepSeek 使用终端命令 ollama list查询deepseek名称,如deepseek-r1:14b。 在Ollama插件冲添加…...
QEMU源码全解析 —— 块设备虚拟化(7)
接前一篇文章:QEMU源码全解析 —— 块设备虚拟化(6) 本文内容参考: 《趣谈Linux操作系统》 —— 刘超,极客时间 《QEMU/KVM源码解析与应用》 —— 李强,机械工业出版社 特此致谢! QEMU初始化阶段的块设备虚拟化 从模板生成类和类的实例化 上一回在讲解QEMU中类继承…...
图论 | 岛屿数量(深搜,广搜)
岛屿数量 acm模式:99.岛屿数量 核心代码模式: 200. 岛屿数量 思路 遍历grid,如果它是1,则通过bfs/dfs将这个小岛的grid变为0 dfs def dfs(grid,i,j):if i<0 or j<0 or i>len(grid) or j>len(grid[0]):returnif g…...
iOS:GCD信号量、同步、异步的使用方法
信号量的详细用法,可以用此方法进行队列管理 -(void)dispatchSignal{//crate的value表示,最多几个资源可访问dispatch_semaphore_t semaphore dispatch_semaphore_create(3);dispatch_queue_t quene dispatch_get_global_queue(DISPATCH_QUEUE_PRIORI…...
MSP430 Proteus 仿真作品
https://www.dong-blog.fun/post/1998 1 、 电子万年历(采用 DS1302 及 及 TC72 等芯片) 基本要求: 可显示年、月、日、星期、时、分、秒; 有温度显示功能。 发挥部分: 可调节时间和日期; 有农历显示功能 &…...
Windows打开ftp局域网共享
前提是windows已经设置好开机账号密码了,否则教程不适用 第一先打开电脑ftp共享配置 点击保存即可 2.设置要共享到其他电脑的文件路径(如果你要共享整个盘你就设置整个盘,如果是共享盘中某文件就设置某文件,这里是某文件&#x…...
基于HTML的邮件发送状态查询界面设计示例
以下是一个基于HTML的邮件发送状态查询界面设计示例,结合筛选功能、状态展示和重新发送操作,采用Bootstrap框架实现响应式布局: <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"&…...
聊聊langchain4j的MCP
序 本文主要研究一下langchain4j对Model Context Protocol (MCP) 的支持 MCP MCP协议规定了两种传输方式: HTTP:客户端请求一个SSE(Server-Sent Events)通道以从服务器接收事件,然后通过HTTP POST请求发送命令。这…...
我爱学算法之——滑动窗口攻克子数组和子串难题(中)
学习算法,继续加油!!! 一、将 x 减到 0 的最小操作数 题目解析 来看这一道题,题目给定一个数组nums和一个整数x;我们可以在数组nums的左边或者右边进行操作(x减去该位置的值)&#…...
从零开始上手huggingface
1. 环境配置 # git 安装:https://git-scm.com/ # git lfs安装:https://git-lfs.com git lfs install # huggingface-cli 安装:https://huggingface.co/docs/hub/index pip install huggingface_hub2. 网站直接下载模型 可能会中断ÿ…...
MySQL 死锁问题分析与解决方案
**** 一、死锁原因分析 死锁通常由以下场景引发: 事务执行顺序不一致:多个事务以不同顺序访问相同资源。索引缺失:全表扫描导致行锁升级为表锁。长事务或大事务:长时间持有锁资源,增加冲突概率。隔离级别设置&#x…...
用 pytorch 从零开始创建大语言模型(六):对分类进行微调
用 pytorch 从零开始创建大语言模型(六):对分类进行微调 6 微调用于分类6.1 微调的不同类别6.2 准备数据集6.3 创建数据加载器6.4 使用预训练权重初始化模型6.5 添加分类头部6.6 计算分类损失和准确率6.7 在监督数据上微调模型6.8 使用LLM进…...
dify1.1.1安装
1、 按照GitHub上操作 下载源码,没有安装git的,可以下载成zip包, unzip 解压 git clone https://github.com/langgenius/dify.git cd dify cd docker cp .env.example .env2、启动前 ,先改下 docker-compose.yaml,…...
Netty——BIO、NIO 与 Netty
文章目录 1. 介绍1.1 BIO1.1.1 概念1.1.2 工作原理1.1.3 优缺点 1.2 NIO1.2.1 概念1.2.2 工作原理1.2.3 优缺点 1.3 Netty1.3.1 概念1.3.2 工作原理1.3.3 优点 2. Netty 与 Java NIO 的区别2.1 抽象层次2.2 API 易用性2.3 性能优化2.4 功能扩展性2.5 线程模型2.6 适用场景 3. 总…...
【Linux】信号:信号保存和处理
🔥个人主页:Quitecoder 🔥专栏:linux笔记仓 目录 01.阻塞信号信号集 02.捕捉信号sigaction可重入函数volatileSIGCHLD 01.阻塞信号 实际执行信号的处理动作称为信号递达:每个信号都有一个默认行为,例如终…...
应用权限组列表
文章目录 使用须知位置相机麦克风通讯录日历运动数据身体传感器图片和视频音乐和音频跨应用关联设备发现和连接剪切板文件夹文件(deprecated) 使用须知 在申请目标权限前,建议开发者先阅读应用权限管控概述-权限组和子权限,了解相关概念,再合…...
MATLAB实现基于“蚁群算法”的AMR路径规划
目录 1 问题描述 2 算法理论 3 求解步骤 4 运行结果 5 代码部分 1 问题描述 移动机器人路径规划是机器人学的一个重要研究领域。它要求机器人依据某个或某些优化原则 (如最小能量消耗,最短行走路线,最短行走时间等),在其工作空间中找到一…...
【深度学习】多目标融合算法(五):定制门控网络CGC(Customized Gate Control)
目录 一、引言 二、CGC(Customized Gate Control,定制门控网络) 2.1 技术原理 2.2 技术优缺点 2.3 业务代码实践 2.3.1 业务场景与建模 2.3.2 模型代码实现 2.3.3 模型训练与推理测试 2.3.4 打印模型结构 三、总结 一、引言 上一…...
【NLP 42、实践 ⑪ 用Bert模型结构实现自回归语言模型的训练】
如果结局早已注定,那么过程就将大于结局 —— 25.3.18 自回归语言模型:由前文预测后文的语言模型 特点:单向 训练方式:利用前n个字预测第n1个字,实现一个mask矩阵,送入Bert模型,让其前文看不到…...
TCP | 序列号和确认号 [逐包分析] | seq / ack 详解
注 : 本文为 “TCP 序号(seq)与确认序号(ack)” 相关文章合辑。 英文引文,机翻未校。 中文引文,略作重排。 如有内容异常,请看原文。 Understanding TCP Seq & Ack Numbers […...
在Linux、Windows系统上安装开源InfluxDB——InfluxDB OSS v2并设置开机自启的保姆级图文教程
一、进入InfluxDB下载官网 InfluxData 文档https://docs.influxdata.com/Install InfluxDB OSS v2 | InfluxDB OSS v2 Documentation...
考研复习之队列
循环队列 队列为满的条件 队列为满的条件需要特殊处理,因为当队列满时,队尾指针的下一个位置应该是队头指针。但是,我们不能直接比较 rear 1 和 front 是否相等,因为 rear 1 可能会超出数组索引的范围。因此,我们需…...
Day 21: 数组中的逆序对
在股票交易中,如果前一天的股价高于后一天的股价,则可以认为存在一个「交易逆序对」。请设计一个程序,输入一段时间内的股票交易记录 record,返回其中存在的「交易逆序对」总数。 示例 1: 输入:record [9…...
【C++教程】setw()函数的使用方法
setw 是 C 中用于设置输出字段宽度的函数,属于 <iomanip> 头文件。以下是其使用方法及注意事项: 基本用法 包含头文件: #include <iostream> #include <iomanip> // 必须包含此头文件 using namespace std; // 避免写 std…...
智慧高速,安全护航:视频监控平台助力高速公路高效运营
随着我国高速公路里程的不断增长,交通安全和运营效率面临着前所未有的挑战。传统的监控方式已难以满足现代化高速公路管理的需求,而监控视频平台的出现,则为高速公路的安全运营提供了强有力的技术支撑。高速公路视频监控联网解决方案 高速公路…...
Jboss漏洞再现
一、CVE-2015-7501 1、开环境 2、访问地址 / invoker/JMXInvokerServlet 出现了让下载的页面,说明有漏洞 3、下载ysoserial工具进行漏洞利用 4、在cmd运行 看到可以成功运行,接下来去base64编码我们反弹shell的命令 5、执行命令 java -jar ysoserial-…...
C语言三大程序结构 单分支语句
核心概念:程序就像流水线,通过顺序、选择、循环三种结构完成复杂任务 🌟 一、三大程序结构图解 结构类型形象比喻代码示例顺序直行马路 → 不拐弯printf("A"); printf("B");选择岔路口 → 二选一if...else循环环形跑道 …...
【Linux系统】Linux权限讲解!!!超详细!!!
目录 Linux文件类型 区分方法 文件类型 Linux用户 用户创建与删除 用户之间的转换 su指令 普通用户->超级用户(root) 超级用户(root) ->普通用户 普通账户->普通账户 普通用户的权限提高 sudo指令 注: Linux权限 定义 权限操作 1、修改文…...
Winform零基础从入门到精通(5)——WinForm菜单与工具栏开发详解
一、核心控件与功能 MenuStrip(顶部菜单栏) • 功能:创建应用程序主菜单,支持多级子菜单和快捷键。 • 关键操作: ◦ 添加菜单项:直接在菜单栏输入文字(如“文件(F)”),…...

