【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. ...
随机推荐
- [转帖]exportfs命令
https://www.cnblogs.com/xzlive/p/9766388.html exportfs命令:功能说明 :NFS共享管理语法格式exportfs [必要参数][选择参数][目录]功 ...
- VM PowerCli的简单安装和使用学习
1. Win10 上面安装 下载 zip包并且进行安装 win10 已经带了powershell 安装比较简单, 只不过安装时会提示 powershell的权限有问题需要打开powershell 执行 ...
- echarts饼状图不要中间的文字提示
饼状图不要中间的文字提示信息 emphasis: { label: { show: false, //将这个设置为false }, }, 为什么饼状图不要中间的问题提示信息 因为有些时候,在文字很多的 ...
- 从零开始配置vim(27)——代码片段
我们之前介绍过缩写相关的内容,缩写是可以自动帮我们将缩写的单词展开成一段完整的话.但是代码本身是结构话的,仅仅使用缩写来配置是无法完成自动生成代码这个步骤的.好在我们大量的插件来进行配置.本篇我们将要 ...
- MySQL 中使用变量实现排名名次
title: MySQL 中使用变量实现排名名次 date: 2023-7-16 19:45:26 tags: - SQL 高级查询 一. 数据准备: CREATE TABLE sql_rank ( ...
- java8新特性知识整理
目录 前言 Lambda 表达式 方法引用 函数式接口 Stream 流 构造流的几种方式 常用 api Collectors.toMap (List 转 Map) peek 和 map 区别 gro ...
- 【主流技术】实战之 Spring Boot 中集成微信支付(小程序)
前言 微信支付是企业级项目中经常使用到的功能,作为后端开发人员,完整地掌握该技术是十分有必要的. 以下是经过真实商业项目实践的集成步骤,包括注册流程.调用过程.代码demo(经过脱敏)等,希望我的分享 ...
- 常用排序方法——python写法【冒泡、快速排序、TOP-K问题】
1.冒泡排序 相信冒泡排序是很多小伙伴第一个知道的排序算法.它就是每趟排序冒出一个最大(最小)值,相邻两个元素比较,前一个比后一个大,则交换. def bubbleSort(arr): n = len ...
- 【3】jupyter notebook【修改主题、字体、字号、代码自动补全、变更工作目录、添加目录插件、解决工具栏隐藏问题、修改默认浏览器、默认打开位置】
相关文章: [1]Anaconda安装超简洁教程,瞬间学会! [2]Anaconda下:ipython文件的打开方式,Jupyter Notebook中运行.py文件,快速打开ipython文件的方法 ...
- Python通过SNMP监控网络设备
前段时间,为了实现自动化巡检,我开发了自动化巡检工具,由于我的系统设备版本比较多,所以我是分别开发的客户端程序,服务端使用dll文件与客户端通信,服务端的dll在与python通信,通过Python丰 ...