题目信息

  • 时间: 2019-07-03

  • 题目链接:Leetcode

  • tag: 单链表

  • 难易程度:简单

  • 题目描述:

    输入两个链表,找出它们的第一个公共节点。

示例:

  1. A a1 -> a2
  2. \
  3. -> c1 -> c2 -> c3
  4. /
  5. Bb1 -> b2 -> b3

注意

  1. 1. 如果两个链表没有交点,返回 null.
  2. 2. 在返回结果后,两个链表仍须保持原有的结构。
  3. 3. 可假定整个链表结构中没有循环。
  4. 4. 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。

解题思路

本题难点

两条链表不一样长,其到达交点的路程不一样。时间复杂度有要求。

具体思路

使用两个指针 node1,node2 分别指向两个链表 headA,headB 的头结点,然后同时分别逐结点遍历。

  • 当 node1 到达链表 headA 的末尾时,重新定位到链表 headB 的头结点;

  • 当 node2 到达链表 headB 的末尾时,重新定位到链表 headA 的头结点。

当它们相遇时,所指向的结点就是第一个公共结点。

代码

  1. public class Solution {
  2. public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
  3. if(headA == null || headB == null){
  4. return null;
  5. }
  6. ListNode node1 = headA;
  7. ListNode node2 = headB;
  8. //两分叉长度一致时,即A B链表长度相同且存在公共节点,此时,不等node1走完A链表(node2走完B链表)即可获得公共节点;
  9. //两分叉不同且存在公共节点时,此时即为最开始分析时的思路,node1,node2分别走完两链表的所有长度,并在节点处相遇。
  10. //不存在公共节点,此时最终离开循环时,node1=node2=null,两链表A,B长度相同时,node1,node2只要分别遍历完自己的那条链表就行; 两链表长度不同时,node1先遍历A链表,再遍历B链表,node2先遍历B链表,再遍历A链表,由于A链表+B链表长度固定,等价于node1,node2分别遍历一条长度为A+B的链表,最终一起指向null,循环结束;
  11. while(node1 != node2){
  12. node1 = node1 != null ? node1.next : headB;
  13. node2 = node2 != null ? node2.next : headA;
  14. }
  15. return node1;
  16. }
  17. }

复杂度分析:

  • 时间复杂度 O(M+N) :第一个链表的长度为 m,第二个链表的长度为n,两链表遍历一次花费的时间。
  • 空间复杂度 O(1) : 使用常数大小的额外空间。

其他优秀解答

解题思路

双链指针同时移动,确保同时到链表尾。先确定哪个指针路程长,让其先走几个结点。

  • 辅助函数getLength(ListNode head)用于计数某个链表的长度:通过移动指针temp的循环确定链表长度。
  • 通过lengthAlengthB大小,判断哪个指针先走,先走的指针要走的步数即为abs(lengthA-lengthB)
  • "站在同一起跑线后",就可以指针每移动一次,判断是否走到同一个结点,若是,该结点即为交结点。

对于没有交点的情况,最终a与b会同时成为null,然后while循环结束,返回a也就是null

代码

  1. public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
  2. int lengthA = getLength(headA), lengthB = getLength(headB);
  3. ListNode a = headA, b = headB;
  4. if(lengthA > lengthB){
  5. for(int i = 0; i < lengthA - lengthB; i++)
  6. a = a.next;
  7. } else {
  8. for(int i = 0; i < lengthB - lengthA; i++)
  9. b = b.next;
  10. }
  11. while(a != b){
  12. a = a.next;
  13. b = b.next;
  14. }
  15. return a;
  16. }
  17. private int getLength(ListNode head){
  18. int length = 0;
  19. for(ListNode temp = head; temp != null; temp = temp.next, length++);
  20. return length;
  21. }

每日一题 - 剑指 Offer 52. 两个链表的第一个公共节点的更多相关文章

  1. 剑指 Offer 52. 两个链表的第一个公共节点 + 链表 + 第一个公共结点 + 双指针

    剑指 Offer 52. 两个链表的第一个公共节点 Offer_52 题目详情 题解分析 可以使用两个指针 node1,node2 分别指向两个链表 headA,headB 的头结点,然后同时分别逐结 ...

  2. 力扣 - 剑指 Offer 52. 两个链表的第一个公共节点

    题目 剑指 Offer 52. 两个链表的第一个公共节点 思路1(栈) 若两个链表相遇,则从它开始相遇的地方到链表末尾应该都是相同的,那么我们可以将两个链表分别放入两个栈中,然后依次循环比较两个栈顶的 ...

  3. 剑指 Offer 52. 两个链表的第一个公共节点

    题目链接 题目描述: 我的题解: 方法一:双指针法 思路分析: 声明两个指针p1,p2 分别指向链表A.链表B. 然后分别同时逐结点遍历 当 p1 到达链表 headA 的末尾时,重新定位到链表 he ...

  4. [LeetCode]剑指 Offer 52. 两个链表的第一个公共节点

    题解 nodeA走一个链表A(A独有+公共),再走B独有的长度, nodeB走一个链表B(B独有+公共),再走A独有的长度. 结果:两者相遇点即为交点:若没有交点,两者都走到null,会返回null. ...

  5. 【Java】 剑指offer(52) 两个链表的第一个公共结点

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入两个链表,找出它们的第一个公共结点. 思路 蛮力法:遍历第一个 ...

  6. 剑指offer——55两个链表的第一个公共节点

    题目描述 输入两个链表,找出它们的第一个公共结点. 题解: 分别遍历两个链表到链尾,并计算其长度,若最后一个节点相同,则存在公共节点 然后让长链表指针从头先移动长度差个节点,然后两个链表指针一起移动, ...

  7. 【剑指offer】两个链表的第一个公共结点,C++实现

    原创文章,转载请注明出处! 博客文章索引地址 # 题目 #举例 如果两个单向链表有公共的节点,那么这两个链表从第一个公共结点开始,之后所有结点都是重合的,不可能再出现分叉.拓扑结构如下图所示: # 思 ...

  8. Go语言实现:【剑指offer】两个链表的第一个公共结点

    该题目来源于牛客网<剑指offer>专题. 输入两个链表,找出它们的第一个公共结点. Go语言实现: //长度长的先走个长度差,然后ab一起比较后面结点 //长度一样,公共结点可能在首结点 ...

  9. 【剑指offer】两个链表的第一个公共结点

    一.题目: 输入两个链表,找出它们的第一个公共结点. 二.思路: 思路一:模拟数组,进行两次遍历,时间复杂度O(n2) 思路二:假定 List1长度: a+n  List2 长度:b+n, 且 a&l ...

随机推荐

  1. Android如何使用SharedPreferences轻量级储存

    SharedPreferences只能用来存一些基本数据类型,并且存下的量比较小 直接附代码 和XMl布局 package com.example.okhttpdemo; import android ...

  2. Java实现奇偶数排序

    1 问题描述 给定一个整数数组,请调整 数组中数的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分.要求时间复杂度为O(n). 2 解决方案 2.1 一头一尾指针往中间扫描法 pack ...

  3. java实现购物券消费方案

    公司发了某商店的购物券1000元,限定只能购买店中的m种商品.每种商品的价格分别为m1,m2,-,要求程序列出所有的正好能消费完该购物券的不同购物方法. 程序输入: 第一行是一个整数m,代表可购买的商 ...

  4. OC语言-NSMutableArray为什么要用strong来修饰

    Talk is cheap show you my code!  NSMutableArray属性为什么要用strong来修饰,其实就是一个深复制和浅复制的问题. <pre name=" ...

  5. MySQL 8.0权限认证(下)

    MySQL 8.0权限认证(下)   一.设置MySQL用户资源限制   通过设置全局变量max_user_connections可以限制所有用户在同一时间连接MySQL实例的数量,但此参数无法对每个 ...

  6. css3中的@font-face你真的了解吗

    css3中的自定义字体方法@font-face @font-face属性可以让我们自定义网站字体属性,然后引用到想要应用该字体的元素上. 基本语法: @font-face { font-family: ...

  7. foreach 集合又抛经典异常了,这次一定要刨根问底

    一:背景 1. 讲故事 最近同事在写一段业务逻辑的时候,程序跑起来总是报:集合已修改:可能无法执行枚举操作,硬是没有找到什么情况下会导致这个异常产生,就让我来找一下bug,其实这个异常在座的每个程序员 ...

  8. 4a-c++ primer宽字符wchar_t显示设置与输出代码示例

    .. #include <iostream> #include <windows.h> #include <locale> //#include<wchar. ...

  9. .NET进行客户端Web开发又一利器 - Ant Design Blazor

    你好,我是Dotnet9,继上篇介绍Bootstrap风格的BlazorUI组件库后,今天我来介绍另一款Blazor UI组件库:一套基于 Ant Design 和 Blazor 的企业级组件库. 本 ...

  10. 使用本地http的yum源

    使用http作为本地yum源 场景 在生产环境中,有大概好几十台linux同系统版本的操作系统,为了安装普通软件,现在的做法是向每台机器上上传一个iso镜像,然后将镜像挂在,配置本地的yum源,实现基 ...