【基础算法】单链表的OJ练习(3) # 移除链表元素 # 相交链表 #
文章目录
- 前言
- 移除链表元素
- 相交链表
- 写在最后
前言
-
本章的
OJ练习也是相对简单的,只要能够理解解题的思路,并且依照这个思路能够快速的写出代码,我相信,你的链表水平已经足够了。 -
对于
OJ练习(2): ->传送门<-。其中两道题都可运用快慢指针的解题思路,这使得两个题都只需要遍历一次链表即可解答。 -
对于本章,是链表的
OJ练习的最后一篇较为简单的章节,后续的OJ练习将会上难度。
移除链表元素
-
题目链接:-> 传送门 <-。
-
该题目的描述为:给你一个链表的头节点
head和一个整数val,请你删除链表中所有满足Node.val == val的节点,并返回 新的头节点 。

-
这里我们采用的方法是在原链表的基础上重新连接节点,将 Node.val == val 的节点跳过不连接。
-
我们重新定义一个指向新连接的链表的头节点的指针
newhead,然后在定义一个用来连接的指针cur,最终连接好后返回newhead即可。 -
将 Node.val != val 的节点作为新连接的链表的结点 ,如果一开始
head为空或者head链表里全是等于val的结点,(初始化newnode = cur = NULL)此时连接操作就不进行,后面返回newnode(一直为NULL)即可。


下面是代码实现:
struct ListNode* removeElements(struct ListNode* head, int val){// cur为对新连接的链表的连接指针,newhead为新连接的链表的指向头节点的指针struct ListNode* cur = NULL, * newhead = NULL;struct ListNode* tmp = head;while (tmp){if (tmp->val != val) // 如果不等于val就连接{if (newhead == NULL) // 连接时如果新的头为空,就将该节点作为头节点{newhead = cur = tmp;}else // 正常连接{cur->next = tmp;cur = cur->next;}}tmp = tmp->next; // 到下一个节点判断}// 如果head为空或者head链表里面所有节点的val都为所给的val,就说明没有新的头,这里判断是为了防止空指针解引用// 如果是正常情况,需要将新连接的最后一个节点的next指向NULL,如果已经指向NULL,多操作一步也没有问题if (cur) cur->next = NULL;// 最后返回新连接的链表的头return newhead;
}
相交链表
-
题目链接:-> 传送门 <-。
-
该题目描述为:给你两个单链表的头节点
headA和headB,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回null。
也就是:


解题思路:【双指针遍历】
-
首先我们可以先判断这两个链表是否有一个为空或者都为空,有空的情况那么一定不相交,此时直接返回
NULL。 -
如果两个链表相交,那么从相交的那个起始节点开始,后面的长度是相同的。由此我们定义两个指针
pa与pb分别指向headA的头节点与headB的头节点并同时向后遍历链表。 -
如果
pa不为NULL,则移到下一个节点,如果pb不为空,也移到下一个节点。如果第一次遍历pa为空,则将pa指向headB的头节点;如果第一次遍历pb为空,则将pb指向headA的头节点。至于到底相不相交,第二遍遍历会见分晓。 -
我们假设两个链表相交,那么设从相交的初始节点开始到
NULL的长度为n,headA的头节点到相交的初始节点的长度为x,headB的头节点到相交的初始节点的长度为y。按照上一条的思路,当pa第一次遍历到达NULL时,pa一共走了x + n的长度,此时将pa指向headB的头节点;当pb第一次遍历到达NULL时,pb一共走了y + n的长度,此时将pb指向headA的头节点。仔细思考就会发现,pa在headB走到相交的初始节点还需走y的长度,此时pa一共走了x + n + y;pb在headA走到相交的初始节点还需走x的长度,此时pb一共走了y + n + x。这时,pa走的长度与pb走的长度恰好相等,且pa与pb都刚好指向相交的初始节点。所以,该方法能够有效的找出那个相交的初始节点。

- 如果两个链表不相交,也是一样,通过双指针分别依次向后遍历链表。如果两个链表长度相等,最终
pa与pb在第一次遍历的时候就都会到达NULL,此时返回NULL;如果两个链表长度不相等,同样的,在第一次遍历时,只要pa或者pb指向NULL,就将pa或者pb指向另外一个链表的头节点,然后继续遍历。我们假设headA链表的长度为x,headB链表的长度为y,当pa第一次遍历指向NULL时,走的长度为x,此时将pa指向headB的头节点;当pb第一次遍历指向NULL时,走的长度为y,此时将pb指向headA的头节点。不出所料,两个指针在第二次遍历链表时最后同时指向NULL,这是因为,pa在headB的遍历要走的长度为y,此时pa总共走的长度为x + y;pb在headA的遍历要走的长度为x,此时pb总共走的长度为y + x。可以看到,第二次遍历走完两个指针走的长度是相同的,并且两个指针都是指向NULL。所以,两个链表不相交,遍历的两个指针最终都是同时指向NULL。

下面是代码实现:
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {// 如果其中有一个链表为空或者全为空,说明不可能相交,直接返回NULLif(headA == NULL || headB == NULL) return NULL;struct ListNode* pa = headA, * pb = headB;// 对于headA与headB只有相交与不相交的情况// 相交则跳出循环// 不相交则再循环里面就返回// pa == pb说明找到相交的初始节点了,条件判断为假,跳出循环while (pa != pb){// 同步向后遍历pa = pa->next;pb = pb->next;// 如果两个指针都指向空,说明headA与headB不相交if (pa == NULL && pb == NULL) return NULL;// 如果pa遍历完headA就到headB继续遍历if (pa == NULL) pa = headB;// 如果pb遍历完headB就到headA继续遍历if (pb == NULL) pb = headA;} // 这里返回pa或者pb都是可以的,都指向相交的那个初始节点return pa;
}
写在最后
对于单链表的题目练习,最重要的是思路,我们在数据结构阶段要养成画图的习惯,因为它能帮助我们更好的理解。后续还会有单链表相关的题目练习。
感谢阅读本小白的博客,错误的地方请严厉指出噢!
相关文章:
【基础算法】单链表的OJ练习(3) # 移除链表元素 # 相交链表 #
文章目录前言移除链表元素相交链表写在最后前言 本章的OJ练习也是相对简单的,只要能够理解解题的思路,并且依照这个思路能够快速的写出代码,我相信,你的链表水平已经足够了。 对于OJ练习(2) : ->传送门…...
【自用】SpringBoot项目通用类整理
文章目录全局Json序列化Controller日志切面全局异常拦截GlobalExceptionHandlerApiResultBusinessExceptionResponseEntityUtil全局返回体包装MP自动填充接口文档配置类自定义Async异步线程池本文主要整理各类项目中通用的配置类、工具类,便于复查自用。 全局Json序…...
动态规划法(总述)多阶段决策最优化问题
动态规划: 研究最优控制问题提出的 该问题有n个输入,问题的解由这n个输入组成,这个子集必须满足事先给定的条件,这些条件称为约束条件,满足约束条件的可行解可能不只有一个为了衡量可行解的优劣,通常以一些函数的形式&…...
MySQL跨服务器数据映射
MySQL跨服务器数据映射环境准备1. 首先是要查看数据库的federated引擎 开启/关闭 状态2. 打开任务管理器,并重启mysql服务3. 再次查看FEDERATED引擎状态,引擎已启动映射实现问题总结在日常的开发中经常进行跨数据库进行查询数据。 同服务器下跨数据库进…...
利用反射实现通过读取配置文件对类进行实例化-课后程序(JAVA基础案例教程-黑马程序员编著-第十二章-课后作业)
【案例12-3】:利用反射实现通过读取配置文件对类进行实例化 【案例介绍】 1.案例描述 现在有一个项目,项目中创建了一个Person类,在Person类中定义了一个sleep()方法。在工程中还定义了一个Student类继承Person类,在Student类中…...
1.2 CSS文本属性
CSS Text(文本)属性: 定义文本外观,颜色,装饰,缩进,行间距来修饰文本 文本样式 文本缩进 text-indent文本水平对齐方式:text-align文本修饰:text-decoration行高 line-height CSS文本颜色属性…...
SpringCloud之认识微服务
文章目录一、传统项目转型二、走进 SpringCloud三、微服务项目搭建3.1 创建一个 SpringBoot 项目3.2 创建三个 Maven 子工程3.3 为子工程创建 application.yml3.4 引入依赖3.5 数据库 建库建表3.6 编写业务提示:以下是本篇文章正文内容,SpringCloud系列学…...
【go语言之thrift协议二之server端分析】
go语言之thrift协议二serverthrift.TProtocolFactoryTTransportReadWriteCloserContextFlusherReadSizeProviderTProtocolrunServerNewTServerSocketNewCalculatorHandlerNewCalculatorProcessorNewTSimpleServer4server.ServeListenAcceptLoopprocessRequests在上一篇文章分析…...
【办公类05-03】Python批量修改文件名前面的序号(已有的序号错了,需要改成正确的号码)
背景需求下载教程,手动输入编号,有一个编号错误,导致后面所有编号都错了。30实际是29,以此类推怎样才能快速修改编号数字?前期考虑到可能要改编号,所以在每个编号后面加“ ”(空格)&…...
定向模糊测试工具Beacon基本用法
Beacon是一个定向模糊测试工具,给定行号,能够定向探索行号附近的代码区域。主要思想是采用静态分析的方法获取到与目标有关的变量的最弱前置条件(weakest precondition)的信息,并在相关位置插入断言,来提前…...
《程序员面试金典(第6版)》面试题 02.01. 移除重复节点
题目描述 编写代码,移除未排序链表中的重复节点。保留最开始出现的节点。 示例1: 输入:[1, 2, 3, 3, 2, 1] 输出:[1, 2, 3] -示例2: 输入:[1, 1, 1, 1, 2] 输出:[1, 2] 提示: 链表长度在[0, 20000]范…...
如何对web系统开展无障碍测试
Accessibility test(无障碍测试)是一种测试方法,旨在评估软件、网站或其他数字产品的可访问性,以确保它们能够被身体残障或其他特殊需求的用户使用。这些测试通常包括使用辅助技术,如屏幕阅读器和放大器,以…...
使用vite+vue3.0 创建一个cesium基础应用 ----01 项目搭建
使用vitevue3.0 创建一个cesium基础应用 ----01 项目搭建 1.使用yarn创建一个vite项目 我们可以在vite官网找到vite创建项目的命令 https://cn.vitejs.dev/ 可以使用yarn创建项目选择使用vue3.0框架,语言使用js 创建完成后结构如下: 2.找到vite社区中的…...
【Python学习笔记】第二十七节 Python 多线程
一、进程和线程进程:是程序的一次执行,每个进程都有自己的地址空间、内存、数据栈及其他记录运行轨迹的辅助数据。线程:所有的线程都运行在同一个进程当中,共享相同的运行环境。线程有开始、顺序执行和结束三个部分, …...
【id:18】【20分】B. DS顺序表--连续操作
题目描述建立顺序表的类,属性包括:数组、实际长度、最大长度(设定为1000)该类具有以下成员函数:构造函数:实现顺序表的初始化。插入多个数据的multiinsert(int i, int n, int item[])函数,实现在…...
vi编辑器操作指令分享
vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指令。由于对Unix及Linux系统的任何版本,vi编辑器是完全相同的,因此您可以在其他任何介绍vi的地方…...
OSPF与BFD联动配置
13.1.1BFD概念 BFD提供了一个通用的、标准化的、介质无关的、协议无关的快速故障检测机制,有以下两大优点: 对相邻转发引擎之间的通道提供轻负荷、快速故障检测。 用单一的机制对任何介质、任何协议层进行实时检测。 BFD是一个简单的“Hello”协议。两个系统之间建立BFD会…...
jQuery基础
> 🥲 🥸 🤌 🫀 🫁 🥷 🐻❄️🦤 🪶 🦭 🪲 🪳 🪰 🪱 🪴 🫐 🫒 …...
day39|139.单词拆分 背包问题ending
139.单词拆分 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。 注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。 示例 1: 输入: s "leetcode",…...
Shell脚本编程
Shell编程 视频地址https://www.bilibili.com/video/BV1hW41167NW/?p1&vd_source977d52a6b92ce8b6ae67c16fc61f0428 第一章 Shell概述 大数据程序员为什么要学习Shell呢? 需要看懂运维人员编写的Shell程序偶尔会编写一些简单的Shell程序来管理集群…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
