白银挑战——链表高频面试算法题
算法通关村第一关–链表白银挑战笔记
开始时间:2023年7月18日14:39:36
链表
Java中定义一个链表
class ListNode {public int val;public ListNode next;ListNode(int x) {val = x;next = null;}}
1、四种方法解决两个链表第一个公共子节点
解释一下什么是公共节点 如图,从3节点开始就是第一个公共子节点,也就是说我们要找到这个节点,有一下方式。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4bUTJyWi-1690265452150)(链表_面试高频题.assets\image-20230724153946551.png)]
第一种:哈希和集合
思想就是使用遍历的思想进行查找,将链表的数据全部放入两个Map,一个Map 做遍历的操作,另个就和它对比,相等的点一定是第一个公共节点。这样就能找到。
第二种:使用栈
这里需要使用两个栈,分别将两个链表的结点入两个栈,然后分别出栈,如果相等就继续出栈,一直找到最晚出栈的那一组。这种方式需要两个O(n)的空间,所以在面试时不占优势,但是能够很好锻炼我们的基础能力。
第三种:拼接两个字符串
链表A :0-1-2-3-8-7
链表B:s-e-8-7
拼接 AB 、BA
AB:0-1-2-3-8-9-s-e-8-7
BA : s-e-8-7-0-1-2-3-8-9
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y8dYSX09-1690265452152)(链表_面试高频题.assets/image-20230725112957058.png)]
我们发现拼接后从最后的8开始,两个链表是一样的了,自然8就是要找的节点,所以可以通过拼接的方式来寻找交点。这么做的道理是什么呢?我们可以从几何的角度来分析。我们假定A和B有相交的位置,以交点为中心,可以将两个链表分别分为left_a和right_a,left_b和right_b这样四个部分,并且right_a和right_b是一样的,这时候我们拼接AB和BA就是这样的结构:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XEcYRetf-1690265452152)(链表_面试高频题.assets/1688482919103-da7b4f0a-fdf5-473e-9825-ff8ef174e103.png)]
第四种:差和双指针
我们再看另一个使用差和双指针来解决问题的方法。假如公共子节点一定存在第一轮遍历,假设La长度为L1,Lb长度为L2.则|L2-L1|就是两个的差值。第二轮遍历,长的先走|L2-L1|,然后两个链表同时向前走,结点一样的时候就是公共结点了。
public ListNode findFirstCommonNode(ListNode pHead1, ListNode pHead2) {if(pHead1==null || pHead2==null){return null;}ListNode current1=pHead1;ListNode current2=pHead2;int l1=0,l2=0;//分别统计两个链表的长度while(current1!=null){current1=current1.next;l1++;}while(current2!=null){current2=current2.next;l2++;}current1=pHead1;current2=pHead2;int sub=l1>l2?l1-l2:l2-l1;//长的先走sub步if(l1>l2){int a=0;while(a<sub){current1=current1.next;a++;} }if(l1<l2){int a=0;while(a<sub){current2=current2.next;a++;} }//同时遍历两个链表while(current2!=current1){current2=current2.next;current1=current1.next;} return current1;}
2、判断链表是否为回文序列
什么是回文序列 如图所示:简单理解就就是对称
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QBgv6d4C-1690265452153)(链表_面试高频题.assets/image-20230724155012538.png)]
方法1:将链表元素都赋值到数组中,然后可以从数组两端向中间对比。这种方法会被视为逃避链表,面试不能这么干。
方法2:将链表元素全部压栈,然后一边出栈,一边重新遍历链表,一边比较两者元素值,只要有一个不相等,那就不是。
方法3:优化方法2,先遍历第一遍,得到总长度。之后一边遍历链表,一边压栈。到达链表长度一半后就不再压栈,而是一边出栈,一边遍历,一边比较,只要有一个不相等,就不是回文链表。这样可以节省一半的空间。
方法4:优化方法3:既然要得到长度,那还是要遍历一次链表才可以,那是不是可以一边遍历一边全部压栈,然后第二遍比较的时候,只比较一半的元素呢?也就是只有一半的元素出栈, 链表也只遍历一半,当然可以。
方法5:反转链表法, 先创建一个链表newList,将原始链表oldList的元素值逆序保存到newList中,然后重新一边遍历两个链表,一遍比较元素的值,只要有一个位置的元素值不一样,就不是回文链表。
方法6:优化方法5,我们只反转一半的元素就行了。先遍历一遍,得到总长度。然后重新遍历,到达一半的位置后不再反转,就开始比较两个链表。
方法7:优化方法6,我们使用双指针思想里的快慢指针 ,fast一次走两步,slow一次走一步。当fast到达表尾的时候,slow正好到达一半的位置,那么接下来可以从头开始逆序一半的元素,或者从slow开始逆序一半的元素,都可以。
方法8:在遍历的时候使用递归来反转一半链表可以吗?当然可以,再组合一下我们还能想出更多的方法,解决问题的思路不止这些了,此时单纯增加解法数量没啥意义了。
3、合并有序链表
3.1 合并两个有序链表
LeetCode21 将两个升序链表合并为一个新的升序链表并返回,新链表是通过拼接给定的两个链表的所有节点组成的。
解决思路就是 新建一个链,再通过比较那个两个需要排序链,小的就放进来,这样就可以达到题目要求。
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {ListNode newHead = new ListNode(-1);ListNode res = newHead;while (list1 != null && list2 != null) { if (list1.val < list2.val) {newHead.next = list1;list1 = list1.next;} else if (list1.val > list2.val) {newHead.next = list2;list2 = list2.next;} else { //相等的情况,分别接两个链newHead.next = list2;list2 = list2.next;newHead = newHead.next;newHead.next = list1;list1 = list1.next;}newHead = newHead.next;}//下面的两个while最多只有一个会执行while (list1 != null) {newHead.next = list1;list1 = list1.next;newHead = newHead.next;}while (list2 != null) {newHead.next = list2;list2 = list2.next;newHead = newHead.next;}return res.next;
}
优化
进一步分析,我们发现两个继续优化的点,一个是上面第一个大while里有三种情况,我们可以将其合并成两个,如果两个链表存在相同元素,第一次出现时使用if (l1.val <= l2.val)来处理,后面一次则会被else处理掉,什么意思呢?我们看一个序列。
假如list1为{1, 5, 8, 12},list2为{2, 5, 9, 13},此时都有一个node(5)。当两个链表都到5的位置时,出现了list1.val == list2.val,此时list1中的node(5)会被合并进来。然后list1继续向前走到了node(8),此时list2还是node(5),因此就会执行else中的代码块。这样就可以将第一个while的代码从三种变成两种,精简了很多。
第二个优化是后面两个小的while循环,这两个while最多只有一个会执行,而且由于链表只要将链表头接好,后面的自然就接上了,因此循环都不用写,也就是这样:
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {ListNode prehead = new ListNode(-1);ListNode prev = prehead;while (list1 != null && list2 != null) {if (list1.val <= list2.val) {prev.next = list1;list1 = list1.next;} else {prev.next = list2;list2 = list2.next;}prev = prev.next;}// 最多只有一个还未被合并完,直接接上去就行了,这是链表合并比数组合并方便的地方prev.next = list1 == null ? list2 : list1;return prehead.next;}
3.2 合并K个链表
合并k个链表,有多种方式,例如堆、归并等等。如果面试遇到,我倾向先将前两个合并,之后再将后面的逐步合并进来,这样的的好处是只要将两个合并的写清楚,合并K个就容易很多,现场写最稳妥:
public ListNode mergeKLists(ListNode[] lists) {ListNode res = null;for (ListNode list: lists) {res = mergeTwoLists(res, list);}return res;}
3.3 一道很无聊的好题
LeetCode1669:给你两个链表 list1 和 list2 ,它们包含的元素分别为 n 个和 m 个。请你将 list1 中下标从a到b的节点删除,并将list2 接在被删除节点的位置。
1669题的意思就是将list1中的[a,b]区间的删掉,然后将list2接进去,你觉得难吗?如果这也是算法的话,我至少可以造出七八道题,例如:(1)定义list1的[a,b]区间为list3,将list3和list2按照升序合并成一个链表。(2)list2也将区间[a,b]的元素删掉,然后将list1和list2合并成一个链表。(3)定义list2的[a,b]区间为list4,将list2和list4合并成有序链表。
看到了吗?掌握基础是多么重要,我们自己都能造出题目来。这也是为什么算法会越刷越少,因为到后面会发现套路就这样,花样随便变,以不变应万变就是我们的宗旨。
具体到这个题,按部就班遍历找到链表1保留部分的尾节点和链表2的尾节点,将两链表连接起来就行了。
public ListNode mergeInBetween(ListNode list1, int a, int b, ListNode list2) {ListNode pre1 = list1, post1 = list1, post2 = list2;int i = 0, j = 0;while(pre1 != null && post1 != null && j < b){if(i != a - 1){pre1 = pre1.next;i++;} if(j != b){post1 = post1.next;j++;} }post1 = post1.next;//寻找list2的尾节点while(post2.next != null){post2 = post2.next;}//链1尾接链2头,链2尾接链1后半部分的头pre1.next = list2;post2.next = post1;return list1;}
4、双指针专题
5、删除链表元素专题
节点
while(post2.next != null){
post2 = post2.next;
}
//链1尾接链2头,链2尾接链1后半部分的头
pre1.next = list2;
post2.next = post1;
return list1;
}
## 4、双指针专题## 5、删除链表元素专题> 结束时间:
相关文章:
![](https://www.ngui.cc/images/no-images.jpg)
白银挑战——链表高频面试算法题
算法通关村第一关–链表白银挑战笔记 开始时间:2023年7月18日14:39:36 链表 Java中定义一个链表 class ListNode {public int val;public ListNode next;ListNode(int x) {val x;next null;}}1、四种方法解决两个链表第一个公共子节点 解释一下什么是公共节点 如…...
![](https://www.ngui.cc/images/no-images.jpg)
海外腾讯云账号:腾讯云高性能计算平台 THPC
高性能计算平台(TencentCloud High Performance Computing,THPC)是一款腾讯云自研的高性能计算资源管理服务,集成腾讯云上的计算、存储、网络等产品资源,并整合 HPC 专用作业管理调度、集群管理等软件,向用…...
![](https://img-blog.csdnimg.cn/983b84c0c5964ef89395ac81bc5743de.png)
eclipse 最新版没有navigator视图如何解决
使用project exploere视图可以显示类似navigator视图 1.显示project exploere视图 window---->show view --->project exploere 2.project exploere视图转换为类似navigator视图 第一步:点击视图右上角三个点或者倒三角,点击fiters and custom…...
![](https://img-blog.csdnimg.cn/2dc2bac6353041e480fc0f1266a85df2.jpeg)
Zynq-Linux移植学习笔记之62- PL挂载复旦微flash
1、背景介绍 现在为了全国产化需要,之前所有的进口flash全部要换成国产flash 2、复旦微flash型号 其中EFM25QU256和EFM25QL256对标winbond的w25q256 nor flash 3、FPGA设置 复旦微flash只支持单线模式,当使用PL侧的IP核访问时,需要设置模式…...
![](https://img-blog.csdnimg.cn/b843ae0ba80d475caabba5ff730e7450.png)
SpringBoot复习:(2)Tomcat容器是怎么启动的?
SpringApplication的run方法包含如下代码: 其中调用的refreshContext代码如下: 其中调用的refresh方法片段如下: 其中调用的refresh方法代码如下: 其中调用的super.refresh方法代码如下: public void refresh() th…...
![](https://www.ngui.cc/images/no-images.jpg)
1 MobileHomeTopicApplication
目录 1 OrderApplication 1.1 引用文件 1.2 #region 字段 1.3 #region 属性 OrderApplication 引用文件using System; using...
![](https://img-blog.csdnimg.cn/43769b297ab44b57af96afeb7d5b2ce8.png)
mpi4py包安装报错
报错情况 #include <mpi.h>^~~~~~~compilation terminated.failure.removing: _configtest.c _configtest.oerror: Cannot compile MPI programs. Check your configuration!!![end of output]note: This error originates from a subprocess, and is likely not a probl…...
![](https://www.ngui.cc/images/no-images.jpg)
C语言进阶-1
1、数据类型 1.1、基本数据类型 数据类型分2类:基本数据类型复合类型 基本类型:char short int long float double 复合类型:数组 结构体 共用体 类(C语言没有类,C有) 1.1.1、内存占用与sizeof运算符 数据…...
![](https://www.ngui.cc/images/no-images.jpg)
Python如何正确解决爬虫过程中的Cookie失效问题?
前言 本文是该专栏的第54篇,后面会持续分享python爬虫干货知识,记得关注。 在python爬虫项目中,Cookie是一种用于在客户端和服务器之间传递信息的技术。在爬取某些网站的时候,可能会需要登录才能正常获取到数据,这个时候就需要用到cookie来解决。通常情况下,需要将cooki…...
![](https://www.ngui.cc/images/no-images.jpg)
维护自己电脑浅析
作为一名计算机用户,维护自己的电脑是非常重要的,这可以保证电脑的正常运行、数据的安全、提高电脑的性能等。在本文中,我将分享一些我个人维护电脑的经验和技巧。 定期清理电脑 电脑在使用过程中会产生大量的临时文件、垃圾文件、缓存文件等…...
![](https://img-blog.csdnimg.cn/8c7914a43ed1475daeb5487c0785ca05.png)
svo2论文
论文题目 SVO: Semidirect Visual Odometry for Monocular and Multicamera Systems 内容 1) 具有最小特征漂移的长特征轨迹; 2) 图像平面中的大量均匀分布的特征; 3)新特征与旧地标的可靠关联(即环路闭…...
![](https://img-blog.csdnimg.cn/c369e561e39d40d59b69500b13850d58.png)
【GoLang】MAC安装Go语言环境
小试牛刀 首先安装VScode软件 或者pycharmmac安装brew软件 brew install go 报了一个错误 不提供这个支持 重新brew install go 之后又重新brew reinstall go 使用go version 可以看到go 的版本 使用go env 可以看到go安装后的配置 配置一个环境变量 vim ~/.zshrc, # bre…...
![](https://www.ngui.cc/images/no-images.jpg)
epoll服务器创建
驱动 #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/io.h> #include <linux/device.h> #include <linux/uaccess.h> #include <linux/poll.h> unsigned int major; char kbuf[128]{0}…...
![](https://www.ngui.cc/images/no-images.jpg)
jdk11环境 提示“因为 accessExternalDTD 属性设置的限制导致不允许 ‘http‘ 访问“bug
在运行mybatis源码的时候,提示一下错误: Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException: ### Error building SqlSession. ### Cause: org.apache.ibatis.builder.BuilderException: Error creating docum…...
![](https://img-blog.csdnimg.cn/aaba74bd18e741a98869270d9743c8bc.png)
Android Studio 的版本控制Git
Android Studio 的版本控制Git。 Git 是最流行的版本控制工具,本文介绍其在安卓开发环境Android Studio下的使用。 本文参考链接是:https://learntodroid.com/how-to-use-git-and-github-in-android-studio/ 一:Android Studio 中设置Git …...
![](https://img-blog.csdnimg.cn/c87eab4d146449be90bc23a84c3c76df.png)
一个 SpringBoot 项目能处理多少请求
首先,这个问题有坑,因为 spring boot 不处理请求,只是把现有的开源组件打包后进行了版本适配、预定义了一些开源组件的配置通过代码的方式进行自动装配进行简化开发。这是 spring boot 的价值。 使用 spring boot 进行开发相对于之前写配置文…...
![](https://www.ngui.cc/images/no-images.jpg)
Python中的r字符串前缀及其用法详解
Python中的r字符串前缀及其用法详解 1. 介绍 1.1 什么是r字符串前缀 在Python中,r字符串前缀是一种特殊的字符串前缀,用于表示原始字符串。当一个字符串以r前缀开始时,它将被视为原始字符串,其中的转义字符将被忽略。 1.2 r字…...
![](https://img-blog.csdnimg.cn/img_convert/c350b27b70e4edf9fc645e214a47dbfc.png)
LabVIEW实现三相异步电机磁通模型
LabVIEW实现三相异步电机磁通模型 三相异步电动机由于经济和出色的机电坚固性而广泛用于工业化应用。这台机器的设计和驱动非常简单,但在控制扭矩和速度方面,它隐藏了相当大的功能复杂性。通过数学建模,可以理解机器动力学。 基于微分方程的…...
![](https://www.ngui.cc/images/no-images.jpg)
读书会-《影响力》
《影响力》这本书的作者罗伯特西奥迪尼时全球知名说服力研究权威。因其在影响力研究领域的开创性,人们将其称为“影响力研究领域的本杰明富兰克林”。这本书从人们的心理状态,进行了很多实验研究,总结出了7大规律。如果从事营销,需…...
![](https://img-blog.csdnimg.cn/img_convert/7e2b42b4996b1f6fd64e304db8af8a74.png)
141. 环形链表
简单 1.9K 相关企业 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链…...
![](https://img-blog.csdnimg.cn/b4ecef4514a54360a9bd5e1626a10ae0.png#pic_center)
学习笔记|大模型优质Prompt开发与应用课(二)|第一节:大模型应用密码—Prompt的一千种打开方式
文章目录 第一节:大模型应用密码—Prompt的一千种打开方式01你可能听过一个小故事1910华盛顿纺织厂罢工事件 02 小问题:哪些场景会被提效类目一︰减少重复性工作的成本(降本)例如∶做策划初稿、写JD、润色文案prompt生成结果prompt生成结果prompt生成结果promptprom…...
![](https://www.ngui.cc/images/no-images.jpg)
QT chart进行画图
说明 QT Chart 是一个用于在 Qt 应用程序中绘制图表的开源库。它提供了多种类型的图表,如线图、柱状图、饼图等,可以用于可视化数据和统计信息。QT Chart 是一个基于 Qt 绘图框架的扩展,可以轻松集成到现有的 Qt 应用程序中。 使用 QT Chart,你可以通过简单的代码来创建和…...
![](https://img-blog.csdnimg.cn/a7a0f1b73ced434690b47ebfa2c29618.png)
Web3将自己写在合约中的代币添加到MetaMask中管理
上文 Web3带着大家根据ERC-20文档编写自己的第一个代币solidity智能合约 带着大家在智能合约中创建了一个自己的代币系统 我们可以在MetaMask中去导入 ganache环境下模拟出来的第一和第二个账号 我们这里 可以看到他们的 ETH 但看不到自己的代币符号 没关系 我们点击这下面的…...
![](https://www.ngui.cc/images/no-images.jpg)
【微信小程序】显示自带的弹窗,包括加载中,成功,错误,提示,警告
在微信小程序中,可以使用以下方法来显示自带的弹窗: 显示加载中的弹窗: wx.showLoading({title: 加载中,mask: true });显示成功的弹窗: wx.showToast({title: 成功,icon: success,duration: 2000 });显示错误的弹窗࿱…...
![](https://www.ngui.cc/images/no-images.jpg)
vue-element-plus-admin框架的tag上下文切换bug
问题 首先贴上该框架的链接:https://github.com/kailong321200875/vue-element-plus-admin 在对路由进行部分修改后,网站多次切换tag时,控制台会出现报错:Cannot read properties of undefined (reading offsetLeft)。 我在框架…...
![](https://www.ngui.cc/images/no-images.jpg)
vue中,父子组件传递参数 props 实现方式
通过 Prop 向子组件传递数据 001:父组件》子组件通信 <template><div><h1>这里是父元素</h1>//******<childComponent :detailMes"detailMes"/></div> </template><script>import childComponent from…...
![](https://www.ngui.cc/images/no-images.jpg)
Unity如何快速接入iOS和GooglePlay的成就排行榜等GameCenter功能
一般在游戏开发中,经常有成就排行榜的需求,按照我们的理解,通常是要自己导入谷歌的sdk,或者苹果的sdk,然后封装后通过桥接来调用。 不用这么复杂,本鱼蛋(egostudio 防爬)告诉大家一个方法,其实…...
![](https://img-blog.csdnimg.cn/c8c0bd39a4cc415992d9a752457035ab.jpeg)
Unity下如何实现低延迟的全景RTMP|RTSP流渲染
技术背景 Unity3D可以用于创建各种类型的的应用程序,包括虚拟现实、培训模拟器等。以下是一些可以使用Unity3D全景播放的场景: 虚拟现实体验:全景视频可以用来创建逼真的虚拟环境,使用户能够感受到身临其境的感觉;培…...
![](https://img-blog.csdnimg.cn/b5ad29f4fa744038801085837069a5a9.png#pic_center)
STM32 USB使用记录:HID类设备(后篇)
文章目录 目的基础说明项目构建与代码调整接收发送代码与测试示例链接报告描述符总结 目的 接上篇: 《STM32 USB使用记录:HID类设备(前篇)》 USB HID 类的设备有个比较大的好处是大部分时候接入主机中都是可以免驱使用的。这篇文…...
![](https://img-blog.csdnimg.cn/035a3552597241539ba771283853fe4e.png)
C# 快速写入日志 不卡线程 生产者 消费者模式
有这样一种场景需求,就是某个方法,对耗时要求很高,但是又要记录日志到数据库便于分析,由于访问数据库基本都要几十毫秒,可在方法里写入BlockingCollection,由另外的线程写入数据库。 可以看到,在…...
![](https://img-blog.csdnimg.cn/20191014083755954.png)
网站模版怎么用/aso优化
最近经常被读者问到有没有 Spring Boot 实战项目可以学习,于是,我就去 Github 上找了 10 个我觉得还不错的实战项目。对于这些实战项目,有部分是比较适合 Spring Boot 刚入门的朋友学习的,还有一部分可能要求你对 Spring Boot 相关…...
![](/images/no-images.jpg)
成品图片的网站在哪里找/如何在百度发布信息
当你看到的时候,你是不是已经爱上了它,如果你真的只看外表,那你就错了,不要太相信自己的眼睛,往往真像并不是你所看到的那么简单!请跟我一起来看看吧! 这次在项目中,就遇到了这个问题…...
![](/images/no-images.jpg)
太原做网站的公司排行/怎么做游戏推广员
模式中的角色 抽象类(AbstractClass):定义了算法的骨架。 具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法。 //抽象模板类 public abstract class AbstractPerson{//抽象类定义整个流程骨…...
![](https://img-blog.csdnimg.cn/a0a0faf4a35043e2806793f8d6d3b52b.png)
网站建设方案浩森宇特/长沙网站优化推广方案
【案例2-5】输入圆的半径计算面积和周长 一、案例描述 考核知识点 toFixed()、isNaN、window.document对象 练习目标 掌握toFixed()方法。掌握数据类型检测。了解windoe.document对象。 需求分析 用JavaScript代码来计算圆的周长和面积,用户自己输入正确的r半径&…...
![](/images/no-images.jpg)
网站导航如何做半透明渐变/百度应用商店app
select date_format(date(current_timestamp()),yyyymmdd)...
![](https://img-blog.csdnimg.cn/864c2f9d8a8543baa2d4c87094982e23.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54Ot6KGA5ZCK6L2m5bC-fg==,size_20,color_FFFFFF,t_70,g_se,x_16)
wordpress批量管理/在线外链
注意事项: 1、被数字[1]标注的垃圾回收器组合在jdk8的时候已被废弃,在jdk9的时候已被删除 2、被数字[2]标注的垃圾回收器组合在jdk14的时候已被删除 3、CMS垃圾回收器在jdk14的时候已被删除 4、CMS在满足某个条件下会被自动替换为Serial Old...