hot100之链表上
相交链表(160)
先看代码
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode p = headA;
ListNode q = headB;
while (p != q){
p = p != null ? p.next : headB;
q = q != null ? q.next : headA;
}
return p;
}
}
- 分析
将A的尾节点与B相连, B的尾节点与A相连

据图可知当(p, q)→(A, B指针)步频一致时, 会共同到达共有链表的初节点
反转链表(206)
先看代码
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null){
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
}
- 分析
通过先置哨兵节点, 避免节点数量过少导致null pointer exception
回文链表(234)
先看代码
class Solution {
public boolean isPalindrome(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while (fast.next != null){
fast = fast.next;
slow = slow.next;
if (fast.next != null){
fast = fast.next;
}
}
ListNode rig = reverse(slow);
ListNode lef = head;
while (rig != null){
if (rig.val != lef.val){
return false;
}
rig = rig.next;
lef = lef.next;
}
return true;
}
private ListNode reverse(ListNode node){
ListNode prev = null;
while (node != null){
ListNode next = node.next;
node.next = prev;
prev = node;
node = next;
}
return prev;
}
}
- 分析
通过快慢指针找到中心节点,反转中心节点后链表,取(lef, rig)→(链表头尾节点) 进行回文分析
环形链表(141)
先看代码
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while (fast != null){
fast = fast.next;
slow = slow.next;
if (fast != null){
fast = fast.next;
}else return false;
if (fast == slow) return true;
}
return false;
}
}
- 通过快慢指针, 快指针相对慢指针移动速度为1, 若有环, 必然追上慢指针
环形链表II(142)
先看代码
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if (fast == slow) break;
}
if (fast == null || fast.next == null) {
return null;
}
slow = head;
while (slow != fast){
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
- 分析
当快慢指针相遇时, 将慢指针置于head, 同步快慢指针步频, 再次相遇即为入口处
证明
f, s 为快慢指针移动的步数
a, b分别为为环外长度, 环内长度
由 f = 2s, f = s + n∗b
有 f = 2n∗b, s = n∗b
因 f + a = 2n∗b + a 此时快指针指向环形链表入口
取p = head, 有 (p+a)%(n∗b) == (f+a)%(n∗b) == a
p 和 f在入口相遇
合并两个有序链表(021)
先看代码
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode p1 =list1;
ListNode p2 =list2;
ListNode dummy = new ListNode(-1) ;
ListNode res = dummy;
while(p1!= null && p2!=null){
if ( p1.val <= p2.val){
dummy.next =p1;
p1 = p1.next;
}else {
dummy.next = p2;
p2 = p2.next;
}
dummy =dummy.next;
}
if (p2 != null){
dummy.next = p2;
dummy= dummy.next;
}
if (p1 != null){
dummy.next = p1;
dummy = dummy.next;
}
return res.next;
}
}
- 分析
通过先置prev哨兵节点, 避免节点数量过少导致null pointer exception
两数相加(002)
先看代码
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(-1);
ListNode p = dummy;
int carry = 0;
while (l1 != null || l2 != null || carry != 0){
if (l1 != null){
carry += l1.val;
l1 = l1.next;
}
if (l2 != null){
carry += l2.val;
l2 =l2.next;
}
p = p.next = new ListNode(carry%10);
carry /= 10;
}
return dummy.next;
}
}
- 分析
carry记录两数相加,并作为传参, 传递给下一循环
删除链表的倒数第 N 个结点(019)
先看代码
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(-1, head);
ListNode sentry = dummy;
ListNode cur = dummy;
for (int i = 0; i < n +1 ; i++) {
sentry =sentry.next;
}
while (sentry != null){
sentry =sentry.next;
cur = cur.next;
}
cur.next = cur.next.next;
return dummy.next;
}
}
- 分析
保持n作为节点相对距离
让sentry先走n步, 当 sentry走到末尾, cur也到了要删除的节点处
两两交换链表中的节点(024)
先看代码
class Solution {
public ListNode swapPairs(ListNode head) {
if (head == null || head.next == null){
return head;
}
ListNode next = head.next;
head.next = swapPairs(next.next);
next.next = head;
return next;
}
}
- 感悟
递归的代码就是简洁
hot100之链表上的更多相关文章
- 148 Sort List 链表上的归并排序和快速排序
在使用O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序. 详见:https://leetcode.com/problems/sort-list/description/ Java实 ...
- 在链表上实现 Partition 以及荷兰国旗问题
在链表上实现 Partition 以及荷兰国旗问题 作者:Grey 原文地址: 博客园:在链表上实现 Partition 以及荷兰国旗问题 CSDN:在链表上实现 Partition 以及荷兰国旗问题 ...
- 单链表上的一系列操作(基于c语言)
单链表的实现分为两种单链表(其实差别并不是很大):带头结点和不带头结点,分别对应下面图中的上下两种. 链表的每一个结点是由两个域组成:数据域和指针域,分别存放所含数据和下一个结点的地址(这都是很明白的 ...
- 数据结构与算法之美 06 | 链表(上)-如何实现LRU缓存淘汰算法
常见的缓存淘汰策略: 先进先出 FIFO 最少使用LFU(Least Frequently Used) 最近最少使用 LRU(Least Recently Used) 链表定义: 链表也是线性表的一种 ...
- LeetCode 148 Sort List 链表上的归并排序和快速排序
Sort a linked list in O(n log n) time using constant space complexity. 单链表排序----快排 & 归并排序 (1)归并排 ...
- ACM-单向链表插入排序算法(在原链表上操作)
/* 1.若链表只有一个节点或者为空,直接返回 2.将链表的前两个节点排序,并将排序之后的第二个节点的下一个节点赋空 3.此时整个链表分为了两个,将未排序的节点一一插入到已排序链表中: 3.1.第 ...
- 002 Add Two Numbers 链表上的两数相加
You are given two non-empty linked lists representing two non-negative integers. The digits are stor ...
- 对于一棵二叉树,请设计一个算法,创建含有某一深度上所有结点的链表。 给定二叉树的根结点指针TreeNode* root,以及链表上结点的深度,请返回一个链表ListNode,代表该深度上所有结点的值,请按树上从左往右的顺序链接,保证深度不超过树的高度,树上结点的值为非负整数且不超过100000。
/* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x ...
- 04 | 链表(上):如何实现LRU缓存淘汰算法?
今天我们来聊聊“链表(Linked list)”这个数据结构.学习链表有什么用呢?为了回答这个问题,我们先来讨论一个经典的链表应用场景,那就是+LRU+缓存淘汰算法. 缓存是一种提高数据读取性能的技术 ...
- 《数据结构与算法之美》 <04>链表(上):如何实现LRU缓存淘汰算法?
今天我们来聊聊“链表(Linked list)”这个数据结构.学习链表有什么用呢?为了回答这个问题,我们先来讨论一个经典的链表应用场景,那就是 LRU 缓存淘汰算法. 缓存是一种提高数据读取性能的技术 ...
随机推荐
- C#/.NET/.NET Core技术前沿周刊 | 第 31 期(2025年3.17-3.23)
前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录.追踪C#/.NET/.NET Core领域.生态的每周最新.最实用.最有价值的技术文章.社区动态.优质项目和学习资源等. ...
- FastAPI数据库集成与事务管理
title: FastAPI数据库集成与事务管理 date: 2025/04/18 00:15:34 updated: 2025/04/18 00:15:34 author: cmdragon exc ...
- 从零实现富文本编辑器#3-基于Delta的线性数据结构模型
数据模型的设计是编辑器的核心基础,其直接影响了选区模型.DOM模型.状态管理等模块的设计.例如在quill中的选区模型是index + len的表达,而slate中则是anchor + focus的表 ...
- thinkphp 命令行执行导入
<?phpdeclare (strict_types=1);namespace app\command;use think\console\Command;use think\console\I ...
- VC6.0工具下载安装
公众号回复:'VC6.0'
- 如何用DevEco Studio的ArkUI Inspector轻松搞定鸿蒙应用UI布局
作为一名鸿蒙应用开发者,我最近遇到了一个让我头疼不已的UI问题--一个看似简单的页面布局,却在真机上出现了严重的错位问题.按钮重叠.文本溢出.图片显示不全--这些问题不仅影响了用户体验,还让我在调试过 ...
- DeepWiki:AI驱动、免费且实用的 GitHub 源码阅读与分析神器!
前言 GitHub 作为全球最大的代码托管平台,汇聚了无数开发者的智慧结晶,为各行各业的技术进步提供了宝贵的资源.然而,面对浩瀚如海的代码库,如何高效地阅读.理解和分析源码,成为了摆在众多开发者面前的 ...
- IDEA问题之“接口路径查询插件【RestfulToolkit】”
一.场景 只查询Java代码中的路径,这样就可以快速的找到对应的接口 快捷键:Ctrl + \ 二.安装步骤
- TensorFlow 基础 (03)
项目再忙碌, 还是要抽出时间来学习的. 最近到整一些数据清洗小工具, 数据导入数据库工具等... 有种感觉是, 之前我做分析师的时候, 啥工具都没有, 全部我自己造, 数据表整理, 业务整理, 建库建 ...
- RPC实战与核心原理之时钟轮
时钟轮在RPC中的应用 回顾 在分布式环境下,RPC 框架自身以及服务提供方的业务逻辑实现,都应该对异常进行合理地封装,让使用方可以根据异常快速地定位问题:而在依赖关系复杂且涉及多个部门合作的分布式系 ...