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

链上相遇,节点之间的悸动与牵连

在这里插入图片描述

公主请阅

  • 1. 返回倒数第 k 个节点
    • 1.1 题目说明
    • 1.2 题目分析
    • 1.3 解法一代码以及解释
    • 1.3 解法二代码以及解释
  • 2.相交链表
    • 2.1 题目说明
      • 示例 1
      • 示例 2
      • 示例 3
    • 2.2 题目分析
    • 2.3 代码部分
    • 2.4 代码分析

1. 返回倒数第 k 个节点

在这里插入图片描述

题目传送门


1.1 题目说明

题目名称:
面试题 02.02. 返回倒数第k个节点

题目要求:
实现一种算法,找出单向链表中倒数第 k 个节点,并返回该节点的值。

注意:
本题相对原题稍作改动。

示例:
输入:1 -> 2 -> 3 -> 4 -> 5 和 k = 2
输出:4

说明:
给定的k保证是有效的。


1.2 题目分析

这个题的话需要我们将倒数第k个节点进行返回,那么我们先想到的是什么呢?怎么找打倒数第k个节点呢?
解法一
那么这个时候我就想着将这个链表先逆置了,然后遍历k次我们就可以找到原先链表的倒数第k个节点了
这个是一种解法

解法二
要解决这个问题,我们可以使用 双指针(又称为 快慢指针)来找到链表中的倒数第 k 个节点。具体思路如下:

  1. 初始化两个指针,都指向链表的头节点。

    • 快指针 fast
    • 慢指针 slow
  2. 移动快指针,先让 fast 指针前进 k 步。

  3. 同时移动快慢指针,当 fast 指针到达链表末尾时,slow 指针的位置就是倒数第 k 个节点的位置。

详细步骤:

  1. 定义 fastslow 两个指针,初始时都指向链表头部。
  2. fast 先走 k 步,这样在之后的同时移动中,fastslow 之间的距离始终保持 k
  3. 然后同时移动 fastslow,每次 fast 向后移动一格,直到 fast 到达链表的末尾。
  4. 此时,slow 就是倒数第 k 个节点。

那么下面我们会将两个解决方案的代码呈现出来的


1.3 解法一代码以及解释

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/int kthToLast(struct ListNode* head, int k)
{struct ListNode*prev=NULL;struct ListNode*cur=head;while(cur!=NULL)//遍历整个链表,将链表反转了{struct ListNode*tmp=cur->next;cur->next=prev;prev=cur;cur=tmp;}//到这里prev就是反转链表的头结点了while(--k){prev=prev->next;}return prev->val;
}//先将链表进行反转的操作,然后我们就可以直接利用循环来找到第k个节点了

先定义两个指针

-prev指向当前节点的前一个节点,初始化为NULL

  • cur指向当前节点,初始化为头结点

然后我们使用while循环进行遍历操作,直到我们遍历到尾节点我们就结束了
我们先定义一个指针tmp将当前节点的下一个节点进行保存了
然后我们现在开始将相邻的两个节点的指向进行改变的操作了
我们让当前节点的下个节点指向我们的prev,然后对prev这个指向进行更新,现在指向了我们当前的节点了,然后我们的cur也进行了更新了,指向当前节点的下个节点了,下个节点我们一开始使用tmp进行保存了,然后我们直接进行赋值就行了
等循环结束了,我们的链表的遍历操作就结束了,那么就说明我们的链表已经逆置成功了,那么现在我们的prev就是我们的头结点了
然后我们从这个头结点进行遍历操作,我们遍历k次,所以我们的循环条件是--k,前置–,返回的是-之前的值
等循环结束了,我们的perv就是我们原先链表的倒数第k个节点了,我们直接将这个节点的值进行返回就行了


1.3 解法二代码以及解释

int kthToLast(struct ListNode* head, int k){struct ListNode* first = head;struct ListNode* last = head;for(int i = 1; i < k ;i++)first = first->next;while(first->next){first = first->next;last=last->next;}return last->val;
}

我们先创建了两个指针fastlast,然后都初始化指向头结点,但是我们让块指针先走k步,然后我们继续使用while循环进行遍历操作,但是是快慢指针一起进行遍历,然后循环的条件就是快指针走到了尾节点的时候我们直接将尾节点的值进行返回就行了
但是这个原理是为什么呢?

双指针法的原理可以通过以下几点进行解释:

  1. 快慢指针之间的距离固定为 k
    双指针法的核心思想是利用两个指针:一个“快指针”(fast)和一个“慢指针”(slow)。我们首先让 快指针先走 k,这样快指针和慢指针之间的距离就正好是 k

  2. 同时移动快指针和慢指针
    接下来,当我们同时移动快慢指针时,快指针每走一步,慢指针也走一步。因为快指针最开始已经领先 k 步,因此当快指针走到链表末尾时,慢指针的位置就是倒数第 k 个节点。

  • 具体来说,假设链表的长度为 n,当快指针走到末尾时,它已经走了 n 步。而由于快指针最开始比慢指针多走了 k 步,因此慢指针只走了 n - k 步,此时 slow 就恰好指向倒数第 k 个节点。
  1. 保持链表的一次遍历
    通过这种方式,我们只需要遍历链表一次,而不是两次就可以得到倒数第 k 个节点。相比于朴素方法(先遍历链表得到链表长度,再遍历到目标节点位置)要遍历两次链表的时间复杂度,双指针法将时间复杂度从 O(2n) 优化到了 O(n)

总结原理:

  • 步数差:快指针和慢指针在一开始保持 k 步的差距,这样当快指针到达末尾时,慢指针正好停在倒数第 k 个节点的位置。
  • 一次遍历:只需要遍历链表一次就能完成任务,避免了多次遍历的低效。
  • 指针同步移动:当快指针到达链表末尾时,慢指针正好位于我们想要的倒数第 k 个节点。

2.相交链表

在这里插入图片描述

题目传送门


2.1 题目说明

从图中提取的题目信息如下:

题目描述
给你两个单链表的头节点 headAheadB,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,则返回 null
在这里插入图片描述

注意:

  • 整个链表结构中不存在环。
  • 你不能更改链表的结构,链表必须保持其原始结构。

示例 1

在这里插入图片描述

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at '8'

示例 2

在这里插入图片描述

输入:intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Intersected at '2'

示例 3

在这里插入图片描述

输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null

输入参数:

  • intersectVal:相交的起始节点的值。如果不存在相交节点,则该值为 0。
  • listA:链表 A。
  • listB:链表 B。
  • skipA:在链表 A 中(从头节点开始)跳到交叉节点的节点数。
  • skipB:在链表 B 中(从头节点开始)跳到交叉节点的节点数。

输出:

  • 如果链表相交,返回相交的起始节点的值;如果不相交,返回 null

2.2 题目分析

这个题给我们两个链表,让我们找出两个链表的相交链表,然后将相交节点进行返回的操作,如果没有相交的节点的话我们直接返回NULL
那么这个题我们应该怎么进行设置呢?
可能给的两个链的长度不一样啊,那么我们应该怎么解决呢?
我们可以找出长链,然后计算出两个链的节点之差k,然后让长链走k次,那么我们的长链和短链就是同一个起点了,然后一起进行遍历的操作,边遍历边进行大小的比较的操作,如果两个链表遍历的指针相遇了的话,那么当前的指针所处的节点就是相交的节点了
那么思路就说到这里了,下面就是我们的代码的实践了


2.3 代码部分

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*///我们需要找到两个链表节点的差值//长链表先走差值数//两个链表开始遍历操作,看看是不是同一个节点typedef struct ListNode ListNode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)
{if(headA==NULL||headB==NULL){return NULL;}//创建两个指针分别指向A和B两个链表ListNode*l1=headA;ListNode*l2=headB;//计算两个链表的节点的个数int sizeA=0,sizeB=0;while(l1!=NULL)//先遍历l1{sizeA++;l1=l1->next;}while(l2!=NULL)//先遍历l1{sizeB++;l2=l2->next;}//求差值int gap=abs(sizeA-sizeB);//绝对值//我们需要判断下谁是长链表//我们先假设ListNode*longlist=headA;ListNode*shortlist=headB;if(sizeA<sizeB){longlist=headB;shortlist=headA;}//到这里我们就知道长短链表了while(gap--){longlist=longlist->next;}//上面的代码是找到长链表然后让长链表的指针走差值while(longlist&&shortlist)//两个链表不为空的话我们就往后面走{if(longlist==shortlist)//说明相交了{return longlist;}//如果没有相交的话,那么我们的两个指针接着走longlist=longlist->next;shortlist=shortlist->next;}//到这里的话据说明没有相交的节点,我们直接返回空就行了return NULL;}

2.4 代码分析

我们先将特殊情况进行分析下,如果两个链表都是空的话,我们直接返回NULL就行了
然后我们就开始处理正常情况了
我们先创建两个指针分别指向我们的AB两个链表,分别是l1l2,指向对应链表的头结点
我们然后创建两个变量进行记录两个链表的头结点到尾节点的节点个数
然后我们就可以算出差值gap了,然后我们进行长短链表的判断假设,我们先假设长链表是A,然后加链表是B,如果sizeA<sizeB的话,那么长链表就是B,短链表就是A
然后我们就可以将长短链表判断出来了
我们利用sizeA<sizeB算出了节点差值 gap,我们利用abs进行绝对值的操作
直到长链表是谁之后,我们让长链表走gap
走完之后我们的两个链表一起进行遍历,使用while循环,条件是两个链表不为空我们就往后走
然后在循环里面进行判断,如果长链表的指针等于短链表的指针,那么就说明两个指针相遇了,那么这个节点就是我们想要的相交节点了
在这个条件判断之后我们进行两个指针的往后走一位的操作
如果出了循环还没有返回的话,那么就说明这两个链表是不存在相交的节点的,我们直接返回NULL就行了

相关文章:

链上相遇,节点之间的悸动与牵连

公主请阅 1. 返回倒数第 k 个节点1.1 题目说明1.2 题目分析1.3 解法一代码以及解释1.3 解法二代码以及解释 2.相交链表2.1 题目说明示例 1示例 2示例 3 2.2 题目分析2.3 代码部分2.4 代码分析 1. 返回倒数第 k 个节点 题目传送门 1.1 题目说明 题目名称&#xff1a; 面试题 02…...

一些简单的编程题(Java与C语言)

引言&#xff1a; 这篇文章呢&#xff0c;小编将会举一些简单的编程题用来帮助大家理解一下Java代码&#xff0c;并且与C语言做个对比&#xff0c;不过这篇文章所出现的题目小编不会向随缘解题系列里面那样详细的讲解每一到题&#xff0c;本篇文章的主要目的是帮助小编和读者们…...

java计算机毕设课设—愤怒小鸟游戏(附源码、文章、相关截图、部署视频)

这是什么系统&#xff1f; 资源获取方式再最下方 java计算机毕设课设—愤怒小鸟游戏(附源码、文章、相关截图、部署视频) 基于Java的愤怒小鸟游戏&#xff0c;我们不仅复刻了原版游戏的核心玩法&#xff0c;还增加了一些创新元素。游戏以2D图形界面呈现&#xff0c;玩家需要…...

【ARM】MDK-Flex服务管理软件使用说明

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 记录MDK网络版部署工具Imtools.exe 的各个界面中相关配置的功能说明 2、 问题场景 解决客户咨询&#xff0c;该服务管理软件如何使用&#xff0c;为客户使用服务管理软件后期自行维护增加一定指导作用。 3、软硬件环…...

【H2O2|全栈】WPS/Office系列有哪些好用的快捷方式?

目录 WPS/Office 前言 准备工作 Office通用快捷键 PPT快捷键 Excel快捷键 Word快捷键 结束语 WPS/Office 前言 本章节属于前端前置知识&#xff0c;即使不学习前端&#xff0c;在工作中掌握常见的WPS/Office办公技能也是十分重要的。在本篇中&#xff0c;我将会分享常…...

对比学习)

目录 概念 数据增强 损失函数 NCE&#xff08;noise contrastive estimation&#xff09; Info NCE CV上的发展 InstDisc InvaSpread CPC CMC MoCo simCLR MoCo v2 SimCLR v2 SwAV BYOL SimSiam MoCo v3 DiNO 概念 通过利用样本之间的相似性和不相似性&…...

第十六届蓝桥杯嵌入式真题

蓝桥杯嵌入式第十二届省赛真题二 蓝桥杯嵌入式第十三届省赛真题一 蓝桥杯嵌入式第十三届省赛真题二 蓝桥杯嵌入式第十四届省赛真题 蓝桥杯嵌入式第十四届模拟考试一 蓝桥杯嵌入式第十四届模拟考试二 蓝桥杯嵌入式第十五届模拟考试一 蓝桥杯嵌入式第十五届模拟考试二 蓝…...

音频转码常用命令

1.转码为wav8k16bit -v提高音量 pitch调高音调 speed调整语速 sox -v 2.0 input.wav -r 8000 output.wav pitch 50 speed 1.05 sox input.wav -r 8000 output.wav 只是转码&#xff0c;不提高音调语速 压缩文件&#xff1a;zip -r filename.zip file1 file2 file3 2.批量转…...

INNER JOIN、LEFT JOIN 和 RIGHT JOIN有什么区别?什么是自连接?

INNER JOIN、LEFT JOIN 和 RIGHT JOIN 都是多表连接的不同方式&#xff0c;它们的主要区别在于它们如何处理表之间不匹配的数据。下面分别介绍它们的区别。 目录 一.多表连接查询 INNER JOIN&#xff08;内连接&#xff09; LEFT JOIN&#xff08;左连接&#xff09; RIGHT…...

原型模式具体和直接调用构造函数创建实例的区别

原型模式与直接调用构造函数创建实例的区别主要在于创建对象的方式和使用场景。让我们一步一步来理解。 直接调用构造函数创建实例 这是我们通常使用的创建对象的方法。通过调用类的构造函数&#xff0c;传入必要的参数来初始化对象。每次都要通过构造函数为对象设置所有初始值…...

MySQL 数据备份与恢复指南

本文将介绍如何通过命令行对 MySQL 数据库进行备份与恢复操作&#xff0c;适用于日常开发和生产环境中的数据管理需求。 1. MySQL 数据备份 MySQL 提供了 mysqldump 工具来执行数据库的备份操作&#xff0c;可以备份单个数据库、多个数据库或整个数据库实例。 1.1 备份单个数…...

NGINX 保护 Web 应用安全之基于 IP 地址的访问

根据客户端的 IP 地址控制访问 使用 HTTP 或 stream 访问模块控制对受保护资源的访问&#xff1a; location /admin/ { deny 10.0.0.1; allow 10.0.0.0/20; allow 2001:0db8::/32; deny all; } } 给定的 location 代码块允许来自 10.0.0.0/20 中的任何 IPv4 地址访问&#xf…...

数据结构——顺序表的基本操作

前言 介绍 &#x1f343;数据结构专区&#xff1a;数据结构 参考 该部分知识参考于《数据结构&#xff08;C语言版 第2版&#xff09;》24~28页 补充 此处的顺序表创建是课本中采用了定义方法为SqList Q来创建&#xff0c;并没有使用顺序表指针的方法&#xff0c;具体两个…...

智能去毛刺:2D视觉引导机器人如何重塑制造业未来

机器人技术已经深入到各个工业领域中&#xff0c;为制造业带来了前所未有的变革。其中&#xff0c;2D视觉引导机器人技术以其精准、高效的特点&#xff0c;在去毛刺工艺中发挥着越来越重要的作用。本文将为您介绍2D视觉引导机器人技术的基本原理及其在去毛刺工艺中的应用&#…...

计算机系统的层次

目录 计算机系统的层次ISA&#xff08;指令集体系结构&#xff09; 计算机系统的层次 计算机硬件是基础指令集体系结构&#xff1a;将硬件的功能封装从指令供软件使用操作系统&#xff1a;提供人机交互界面、提供服务功能的内核例程语言处理系统&#xff1a; 语言处理程序&…...

一起搭WPF架构之LiveCharts.Wpf的简单了解与安装

一起搭WPF架构之LiveCharts.Wpf的简单了解与安装 前言LiveCharts.Wpf介绍LiveCharts.Wpf的安装总结 前言 根据项目需求&#xff0c;我单独留了一个界面用于进行数据分析。数据分析的内容考虑是采用图表的形式将SQLite数据库中存储的数据进行绘制成图&#xff0c;以便数据分析。…...

深度学习杂乱知识

阿达玛乘积&#xff08;Hadamard Product&#xff09;详解 1. 定义&#xff1a; 阿达玛乘积&#xff08;Hadamard Product&#xff09;&#xff0c;又称为元素乘积或逐元素乘积&#xff0c;是指对两个维度相同的矩阵进行逐元素相乘的操作。 假设我们有两个维度相同的矩阵 ( …...

本地编译运行Thingsboard-gateway之python版本——modbus数据采集

1、ideal 我用的是2020版本&#xff0c;这个关系不大&#xff0c;随便 Thingsboard-gateway之python版本源码拉取&#xff08;老版本是java写的&#xff0c;新版都是python写的&#xff09; 地址&#xff1a;git clone https://github.com/thingsboard/thingsboard-gateway.git…...

京东笔试题

和谐敏感词 &#x1f517; 题目地址 &#x1f389; 模拟 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner new Scanner(System.in);int n scanner.nextInt();String s scanner.next();String[] words new String[…...

URP学习(一)

URP是unity出的比较简单的可供改造引擎渲染管线的流程。能实现用较低的代价消耗实现较好的效果。 现记录学习&#xff1a; 一.如何设置URP关键 这步结束后材质会被替换 加package Create/Rendering/URP Universal Rendering Setting设置为urp 材质也需要urp目录下的 几种…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散

前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说&#xff0c;在叠衣服的过程中&#xff0c;我会带着团队对比各种模型、方法、策略&#xff0c;毕竟针对各个场景始终寻找更优的解决方案&#xff0c;是我个人和我司「七月在线」的职责之一 且个人认为&#xff0c…...

大数据治理的常见方式

大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法&#xff0c;以下是几种常见的治理方式&#xff1a; 1. 数据质量管理 核心方法&#xff1a; 数据校验&#xff1a;建立数据校验规则&#xff08;格式、范围、一致性等&#xff09;数据清洗&…...

云原生安全实战:API网关Envoy的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关 作为微服务架构的统一入口&#xff0c;负责路由转发、安全控制、流量管理等核心功能。 2. Envoy 由Lyft开源的高性能云原生…...