【LeetCode链表#12】链表相交
链表相交
同:160.链表相交
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
图示两个链表在节点 c1 开始相交:

题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
示例 1:

示例 2:

示例 3:


思路
根据LeetCode题目下的隐藏提示4以及观察可知:
如果两个链表存在相交部分,那么自相交点之后的节点应该都是重合的(下面的图没体现出来)
由此,我们可以将待判断的两个链表的尾部对齐
将较长链表的当前指针指向与短链表的对齐

从此处同时向后遍历,直到找到相同的节点
思路大概是这样的,那么关键要解决两个问题:
1、如何找出较长的那个链表?
2、如何尾部对齐?
因为我们有两个链表,那么先直接定义两个指针curA和curB,并且,curA一定是指向较长的那个链表的指针。
实际上第一个问题用遍历解决就行了,但是在过程中,万一最开始定义的链表并不是最长的,应该如何处理?例如curA实际上比curB短,这时需要将两者调换
调换过程也比较简单粗暴,当记录长度的变量显示curA比curB短后,将curA和curB交换就行(同时还要将长度变量互换)
这个时候,求出两链表的长度差,将curA移动到curB所在的位置,就能将尾部对齐
代码
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
//初始化两链表的头节点,默认A为较长的那个
ListNode curA = headA;
ListNode curB = headB;
//用于记录链表长度
int lenA = 0;
int lenB = 0;
//分别遍历获取两链表长度
while(curA != null){
lenA++;
curA = curA.next;
}
while(curB != null){
lenB++;
curB = curB.next;
}
//遍历结束重新将指针放回头节点
curA = headA;
curB = headB;
//如果lenB大,就要交换一下
if(lenB > lenA){
//交换节点
ListNode tempN;
tempN = curA;
curA = curB;
curB = tempN;
//交换长度信息
int tempL = lenA;
lenA = lenB;
lenB = tempL;
}
//尾部对齐
//先计算长度差值
int subResult = lenA - lenB;
//移动指针对齐短链表
while(subResult-- > 0){
curA = curA.next;
}
//两链表同时向后遍历,遇到相同值便返回
while(curA != null){
if(curA == curB){
return curB;//A、B都行
}
curA = curA.next;
curB = curB.next;
}
return null;
}
}
c++版
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
//初始化两链表的头节点,默认A为较长的那个
ListNode* curA = headA;
ListNode* curB = headB;
//用于记录长度的变量
int lenA = 0;
int lenB = 0;
//分别遍历获取两个链表的长度
while(curA != NULL){
lenA++;
curA = curA->next;
}
while(curB != NULL){
lenB++;
curB = curB->next;
}
//遍历结束,重新将指针放回头结点处
curA = headA;
curB = headB;
//如果B长就交换一下节点
if(lenB > lenA){
// //交换节点
// ListNode* tempNode;
// tempNode = curA;
// curA = curB;
// curB = tempNode;
swap(curA, curB);
//交换长度信息
swap(lenA, lenB);
}
//尾部对齐
//先计算长度差
int subResult = lenA - lenB;
//移动长链表的指针到短链表头位置
while(subResult--){
curA = curA->next;
}
//两链表同时向后遍历,遇到相同值就返回
while(curA != NULL){
if(curA == curB){
return curB;
}
curA = curA->next;
curB = curB->next;
}
return NULL;
}
};
易错点
1、统计完长度记得把指针调回链表头部
2、一定要在处理lenA小于lenB情况的逻辑之前将指针重新置回头节点处,不然结果会有问题
【LeetCode链表#12】链表相交的更多相关文章
- 【LeetCode题解】160_相交链表
目录 160_相交链表 描述 解法一:哈希表 思路 Java 实现 Python 实现 解法二:双指针(推荐) 思路 Java 实现 Python 实现 160_相交链表 描述 编写一个程序,找到两个 ...
- LeetCode算法题-链表类
1.将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. (可以参照第2的merge2List实现) 示例: 输入:1->2->4, 1->3 ...
- Leetcode 25. Reverse Nodes in k-Group 以每组k个结点进行链表反转(链表)
Leetcode 25. Reverse Nodes in k-Group 以每组k个结点进行链表反转(链表) 题目描述 已知一个链表,每次对k个节点进行反转,最后返回反转后的链表 测试样例 Inpu ...
- 经典算法(三) 单链表 反转 & 是否相交/成环 & 求交点 等
参考文章: 判断链表是否相交:http://treemanfm.iteye.com/blog/2044196 一.单链表反转 链表节点 public class Node { private int ...
- LeetCode:分割链表【86】
LeetCode:分割链表[86] 题目描述 给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前. 你应当保留两个分区中每个节点的初始相对位置. 示例 ...
- LeetCode:旋转链表【61】
LeetCode:旋转链表[61] 题目描述 给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: 1->2->3->4->5- ...
- LeetCode:奇偶链表【328】
LeetCode:奇偶链表[328] 题目描述 给定一个单链表,把所有的奇数节点和偶数节点分别排在一起.请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性. 请尝试使用原地 ...
- LeetCode:删除链表中的节点【203】
LeetCode:删除链表中的节点[203] 题目描述 删除链表中等于给定值 val 的所有节点. 示例: 输入: 1->2->6->3->4->5->6, val ...
- LeetCode初级算法--链表01:反转链表
LeetCode初级算法--链表01:反转链表 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/ ...
- LeetCode初级算法--链表02:合并两个有序链表
LeetCode初级算法--链表02:合并两个有序链表 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn. ...
随机推荐
- [转帖]查看x86 cpu睿频命令
查看cpu是否开启睿频,offline掉一些cpu核心后,查看cpu睿频是否升高? turbostat统计X86 处理器的频率.空闲状态.电源状态.温度等状态等 [root@rootbird~]# t ...
- Oracle12c(未更新任何补丁) 使用compression=all 参数导出之后导入失败
1. 最近使用Oracle12c 进行相关的测试工作, 平台linux 和 windows 都有一个问题 备份恢复使用的 compression=all 时导入数据库不管是oracle12c还是 or ...
- Nginx 发布 Docker 运行日志的方法
背景 公司这边想进行容器化负载均衡部署. 脚本很简单, 已经实现了, 但是发现我这边没有ELK也没有LOKI 又不太像切入到容器内部进行 获取日志信息. 所以我这边想了一个别的招来动态刷新日志. 思路 ...
- Spring Cloud 系列:基于Seata 实现 XA模式
https://seata.io/zh-cn/docs/user/mode/xa https://seata.io/zh-cn/docs/dev/mode/xa-mode XA 规范 是 X/Open ...
- NOI Linux 下 Geany 配置教程
没有括号补全? 现在有自动括号补全了! 红色的 a.cpp 的意思是 a.cpp 没有保存. 现在来设置编译运行的快捷键. 不难推测 "%e" 是可执行文件的意思,"%f ...
- 【JS 逆向百例】网洛者反爬练习平台第二题:JJEncode 加密
关注微信公众号:K哥爬虫,持续分享爬虫进阶.JS/安卓逆向等技术干货! 声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后 ...
- LINUX安装和配置
本篇文章为本人从零开始学习linux的学习心得,其中包含了 部署虚拟环境安装linux系统 .其中若有错误之处,请读者积极指出,让本人与读者共同进步. 第一章 部署虚拟环境安装linux系统及配置网路 ...
- 在Protocol Buffers中导入当前目录中的.proto文件
在protobuf中导入当前目录中的.proto文件时,可以使用相对路径.相对路径是相对于当前.proto文件所在的目录来引用其他.proto文件. 假设有以下目录结构: my_project/ |- ...
- errgroup的常见误用
errgroup想必稍有经验的golang程序员都应该听说过,实际项目中用过的也应该不在少数.它和sync.WaitGroup类似,都可以发起执行并等待一组协程直到所有协程运行结束.除此之外errgr ...
- Prompt工程师指南[高阶篇]:对抗性Prompting、主动prompt、ReAct、GraphPrompts、Multimodal CoT Prompting等
Prompt工程师指南[高阶篇]:对抗性Prompting.主动prompt.ReAct.GraphPrompts.Multimodal CoT Prompting等 1.对抗性 Prompting ...