每日一题 - 剑指 Offer 52. 两个链表的第一个公共节点
题目信息
时间: 2019-07-03
题目链接:Leetcode
tag: 单链表
难易程度:简单
题目描述:
输入两个链表,找出它们的第一个公共节点。
示例:
A: a1 -> a2
\
-> c1 -> c2 -> c3
/
B:b1 -> b2 -> b3
注意
1. 如果两个链表没有交点,返回 null.
2. 在返回结果后,两个链表仍须保持原有的结构。
3. 可假定整个链表结构中没有循环。
4. 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。
解题思路
本题难点
两条链表不一样长,其到达交点的路程不一样。时间复杂度有要求。
具体思路
使用两个指针 node1,node2 分别指向两个链表 headA,headB 的头结点,然后同时分别逐结点遍历。
当 node1 到达链表 headA 的末尾时,重新定位到链表 headB 的头结点;
当 node2 到达链表 headB 的末尾时,重新定位到链表 headA 的头结点。
当它们相遇时,所指向的结点就是第一个公共结点。
代码
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA == null || headB == null){
return null;
}
ListNode node1 = headA;
ListNode node2 = headB;
//两分叉长度一致时,即A B链表长度相同且存在公共节点,此时,不等node1走完A链表(node2走完B链表)即可获得公共节点;
//两分叉不同且存在公共节点时,此时即为最开始分析时的思路,node1,node2分别走完两链表的所有长度,并在节点处相遇。
//不存在公共节点,此时最终离开循环时,node1=node2=null,两链表A,B长度相同时,node1,node2只要分别遍历完自己的那条链表就行; 两链表长度不同时,node1先遍历A链表,再遍历B链表,node2先遍历B链表,再遍历A链表,由于A链表+B链表长度固定,等价于node1,node2分别遍历一条长度为A+B的链表,最终一起指向null,循环结束;
while(node1 != node2){
node1 = node1 != null ? node1.next : headB;
node2 = node2 != null ? node2.next : headA;
}
return node1;
}
}
复杂度分析:
- 时间复杂度 O(M+N) :第一个链表的长度为 m,第二个链表的长度为n,两链表遍历一次花费的时间。
- 空间复杂度 O(1) : 使用常数大小的额外空间。
其他优秀解答
解题思路
双链指针同时移动,确保同时到链表尾。先确定哪个指针路程长,让其先走几个结点。
- 辅助函数getLength(ListNode head)用于计数某个链表的长度:通过移动指针temp的循环确定链表长度。
- 通过
lengthA与lengthB大小,判断哪个指针先走,先走的指针要走的步数即为abs(lengthA-lengthB)。 - "站在同一起跑线后",就可以指针每移动一次,判断是否走到同一个结点,若是,该结点即为交结点。
对于没有交点的情况,最终a与b会同时成为null,然后while循环结束,返回a也就是null
代码
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
int lengthA = getLength(headA), lengthB = getLength(headB);
ListNode a = headA, b = headB;
if(lengthA > lengthB){
for(int i = 0; i < lengthA - lengthB; i++)
a = a.next;
} else {
for(int i = 0; i < lengthB - lengthA; i++)
b = b.next;
}
while(a != b){
a = a.next;
b = b.next;
}
return a;
}
private int getLength(ListNode head){
int length = 0;
for(ListNode temp = head; temp != null; temp = temp.next, length++);
return length;
}
每日一题 - 剑指 Offer 52. 两个链表的第一个公共节点的更多相关文章
- 剑指 Offer 52. 两个链表的第一个公共节点 + 链表 + 第一个公共结点 + 双指针
剑指 Offer 52. 两个链表的第一个公共节点 Offer_52 题目详情 题解分析 可以使用两个指针 node1,node2 分别指向两个链表 headA,headB 的头结点,然后同时分别逐结 ...
- 力扣 - 剑指 Offer 52. 两个链表的第一个公共节点
题目 剑指 Offer 52. 两个链表的第一个公共节点 思路1(栈) 若两个链表相遇,则从它开始相遇的地方到链表末尾应该都是相同的,那么我们可以将两个链表分别放入两个栈中,然后依次循环比较两个栈顶的 ...
- 剑指 Offer 52. 两个链表的第一个公共节点
题目链接 题目描述: 我的题解: 方法一:双指针法 思路分析: 声明两个指针p1,p2 分别指向链表A.链表B. 然后分别同时逐结点遍历 当 p1 到达链表 headA 的末尾时,重新定位到链表 he ...
- [LeetCode]剑指 Offer 52. 两个链表的第一个公共节点
题解 nodeA走一个链表A(A独有+公共),再走B独有的长度, nodeB走一个链表B(B独有+公共),再走A独有的长度. 结果:两者相遇点即为交点:若没有交点,两者都走到null,会返回null. ...
- 【Java】 剑指offer(52) 两个链表的第一个公共结点
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 输入两个链表,找出它们的第一个公共结点. 思路 蛮力法:遍历第一个 ...
- 剑指offer——55两个链表的第一个公共节点
题目描述 输入两个链表,找出它们的第一个公共结点. 题解: 分别遍历两个链表到链尾,并计算其长度,若最后一个节点相同,则存在公共节点 然后让长链表指针从头先移动长度差个节点,然后两个链表指针一起移动, ...
- 【剑指offer】两个链表的第一个公共结点,C++实现
原创文章,转载请注明出处! 博客文章索引地址 # 题目 #举例 如果两个单向链表有公共的节点,那么这两个链表从第一个公共结点开始,之后所有结点都是重合的,不可能再出现分叉.拓扑结构如下图所示: # 思 ...
- Go语言实现:【剑指offer】两个链表的第一个公共结点
该题目来源于牛客网<剑指offer>专题. 输入两个链表,找出它们的第一个公共结点. Go语言实现: //长度长的先走个长度差,然后ab一起比较后面结点 //长度一样,公共结点可能在首结点 ...
- 【剑指offer】两个链表的第一个公共结点
一.题目: 输入两个链表,找出它们的第一个公共结点. 二.思路: 思路一:模拟数组,进行两次遍历,时间复杂度O(n2) 思路二:假定 List1长度: a+n List2 长度:b+n, 且 a&l ...
随机推荐
- Java实现LeetCode_0035_SearchInsertPosition
package javaLeetCode.primary; public class SearchInsertPosition_35 { public static void main(String[ ...
- Mac上查看当前安卓手机上打开的app的包名和主程序入口
1.连接上手机,数据线链接或者无线连接随便 2.打开你需要查看的app 3.打开终端,输入命令: adb shell dumpsys window w |grep \/ |grep name=
- 数据结构&算法
20个最常用.最基础数据结构与算法: 10个数据结构:数组.链表.栈.队列.散列表.二叉树.堆.跳表.图.Trie 树. 10个 算法 :递归.排序.二分查找.搜索.哈希.贪心.分治.回溯. ...
- Promise相关学习
what? Promise对象表示一个异步操作的最终状态(完成或失败),以及其返回的值 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/ ...
- x memory pool c语言 内存池
#ifndef X_MEMORY_H #define X_MEMORY_H #include <stdlib.h> #include <stdio.h> #include &l ...
- hadoop知识整理(4)之zookeeper
一.介绍 一个分布式协调服务框架: 一个精简的文件系统,每个节点大小最好不大于1MB: 众多hadoop组件依赖于此,比如hdfs,kafka,hbase,storm等: 旨在,分布式应用中,提供一个 ...
- 0.0---selenium+java自动化基础01---元素定位和操作
一.定位方法 1.通过ID定位元素:driver. findElement(By.id(value)); 2.通过元素的名称定位元素: driver. findElement(By.name( val ...
- 030.Kubernetes核心组件-Scheduler
一 Scheduler原理 1.1 原理解析 Kubernetes Scheduler是负责Pod调度的重要功能模块,Kubernetes Scheduler在整个系统中承担了"承上启下&q ...
- C/S C# WPF锐浪报表教程
前言:锐浪报表是一种中国式报表的报表开发工具.博主使用锐浪报表有一段时间了,积累了一些经验希望能帮助你快速掌握并使用 第一章:集成项目 首先我们先去锐浪报表官网下载并安装锐浪报表. 创建WPF应用程序 ...
- 深入理解JVM(③)ZGC收集器
前言 ZGC是一款在JDK11中新加入的具有实验性质的低延迟垃圾收集器,目前仅支持Linux/x86-64.ZGC收集器是一款基于Region内存布局的,(暂时)不设分代的,使用了读屏障.染色指针和内 ...