【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. ...
随机推荐
- [转帖]如何优雅的使用 Systemd 管理服务
https://zhuanlan.zhihu.com/p/271071439 背景:我们在构建 Kubernetes 容器化平台时,会在节点上部署各种 agent ,虽然容器化当道的今天很多程序可以直 ...
- Booking.com如何在毫秒内搜索数百万个地点
译自:How Booking.com Searches Through Millions of Locations in Milliseconds Booking.com是一家与酒店.旅馆.度假租赁等 ...
- Fabric-ca server端与client端交互
本文介绍Fabric-ca server端和client端的交互过程. 在server端执行Start()命令时,会调用registerHandlers()函数,其作用就是注册处理客户端请求的程序: ...
- 控制node版本
https://blog.csdn.net/qq_46372463/article/details/125357226 这个作者写的操作成功了
- 7.2 通过API创建新进程
创建新的进程是Windows程序开发的重要部分,它可以用于实现许多功能,例如进程间通信.并行处理等.其中,常用的三种创建进程的方式分别是WinExec().ShellExecute()和CreateP ...
- 10.1 C++ STL 模板适配与迭代器
STL(Standard Template Library)标准模板库提供了模板适配器和迭代器等重要概念,为开发者提供了高效.灵活和方便的编程工具.模板适配器是指一组模板类或函数,它们提供一种适配机制 ...
- LyScript 通过PEB结构解析堆基址
LyScript中默认并没有提供获取进程堆基址的函数,不过却提供了获取PEB/TEB的函数,以PEB获取为例,可以调用dbg.get_peb_address(local_pid)用户传入当前进程的PI ...
- 基于.NET实现Matlab备用方案
基于.NET实现Matlab备用方案 今日圈内的朋友都在刷这样的消息: 正值哈工大百年校庆之际,哈工大.哈工程的师生收到了MATLAB软件停止服务的邮件,在与 MATLAB 开发公司 MathWork ...
- 【奶奶看了都会】云服务器ChatGLM模型fine-tuning微调,让你拥有自己的知识库
1.背景 大家好啊,上次给大家写了ChatGLM-6B的部署使用教程,[奶奶看了都会]云服务器部署开源ChatGLM-6B,让你拥有自己的ChatGPT 但是因为模型比较小的问题,所以日常工作中可能用 ...
- [JVM] CPU缓存一致性协议
CPU缓存一致性协议 CPU高速缓存 CPU缓存是位于cpu和内存之间的临时数据交换器,它的容量比内存小的夺但是交换速度要比内存快得多,主要是为了解决cpu运行时的处理速度与内存读写速度不匹配的问题. ...