爱写Bug(ID:iCodeBugs)

编写一个程序,找到两个单链表相交的起始节点。

Write a program to find the node at which the intersection of two singly linked lists begins.

如下面的两个链表

在节点 c1 开始相交。

示例 1:

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Reference of the node with value = 8
输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

示例 2:**

输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Reference of the node with value = 2
输入解释:相交节点的值为 2 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。

示例 3:**

输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
解释:这两个链表不相交,因此返回 null。

注意:

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

Notes:

  • If the two linked lists have no intersection at all, return null.
  • The linked lists must retain their original structure after the function returns.
  • You may assume there are no cycles anywhere in the entire linked structure.
  • Your code should preferably run in O(n) time and use only O(1) memory.

解题思路:

注意:长链表比短链表多出的长度是无需比较的

刚开始我是想着直接从两个链表末尾向前遍历对比节点是否相等,后面才看到是单链表。但是依然有很多的解题方法:

  • 哈希表:把一个链表的节点先存储在哈希表,遍历另一个节点并判断该节点地址是否在哈希表中出现过如果出现过,输出该节点。需要占用额外空间 O(n)。

如果按要求在 O(1) 空间复杂度解题,最容易想到的就是:遍历链表得到链表长度,计算双链表差值,长链表减去差值得到的剩下的链表与短链表长度相等,然后开始比较地址。,当遇到第一个节点地址相同时即为所求。

这个原理简单,但是代码太冗长了,我们来看另一种更优雅的解法,看图帮助理解:

定义两个指针curA、curB分别从链表A、B开始遍历链表,此时最先遇到空节点(到达末尾)的链表即为短链表。

curA、curB走过的长度均为LenA

此时将curA指向链表 B (长链表)的头节点,curB 不变。两个指针开始第二段遍历,直到 curB 遇到空节点(长链表到达末尾)。

此时 curB 走完整个长链表,走的第二段长度就是差值 L。CurA 从长链表头节点开始,与 curB 同步,其走的第二段长度同样是差值 L。

此时 curA 在长链表 剩余未遍历的节点长度是:LenB - L = LenA

此时将 curB 指向链表A的头节点,即将遍历链表A 的长度为 LenA ,则curA、curB剩余即将遍历的长度即为原本需要比较的长度。

开始第三段遍历,遇到第一个相同节点时返回即可。

代码:

Java:

public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) {
return null;
}
ListNode curA = headA;
ListNode curB = headB;
while (curA != curB) {
curA = curA == null ? headB : curA.next;
curB = curB == null ? headA : curB.next;
}
return curA;
}
}

Python:

class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
if not headA or not headB:
return None
curA , curB = headA , headB
while curA != curB:
curA = curA.next if curA else headB
curB = curB.next if curB else headA
return curA

欢迎关注公众号一起学习:爱写Bug

LeetCode 160: 相交链表 Intersection of Two Linked Lists的更多相关文章

  1. [Swift]LeetCode160. 相交链表 | Intersection of Two Linked Lists

    Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...

  2. Java实现 LeetCode 160 相交链表

    160. 相交链表 编写一个程序,找到两个单链表相交的起始节点. 如下面的两个链表: 在节点 c1 开始相交. 示例 1: 输入:intersectVal = 8, listA = [4,1,8,4, ...

  3. LeetCode 160——相交链表(JAVA)

    编写一个程序,找到两个单链表相交的起始节点. 如下面的两个链表: 在节点 c1 开始相交. 示例 1: 输入:intersectVal = 8, listA = [4,1,8,4,5], listB ...

  4. LeetCode 160. 相交链表(Intersection of Two Linked Lists)

    题目描述 编写一个程序,找到两个单链表相交的起始节点. 例如,下面的两个链表: A: a1 → a2 ↘ c1 → c2 → c3 ↗ B: b1 → b2 → b3 在节点 c1 开始相交. 注意: ...

  5. LeetCode 160 相交链表

    题目: 编写一个程序,找到两个单链表相交的起始节点. 如下面的两个链表: 在节点 c1 开始相交. 示例 1: 输入:intersectVal = 8, listA = [4,1,8,4,5], li ...

  6. leetcode 160相交链表

    暴力解法当然可以遍历两个链表,不过time O(mn) space O(1)暂且不说, 方法一:双指针, time O(m+n),space O(1) 可以对比判断环形链表的快慢指针法. 这种方法构思 ...

  7. LeetCode 160. 相交链表 (找出两个链表的公共结点)

    题目链接:https://leetcode-cn.com/problems/intersection-of-two-linked-lists/ 编写一个程序,找到两个单链表相交的起始节点. 如下面的两 ...

  8. [LeetCode]160.Intersection of Two Linked Lists(2个链表的公共节点)

    Intersection of Two Linked Lists Write a program to find the node at which the intersection of two s ...

  9. [LeetCode] 160. Intersection of Two Linked Lists 解题思路

    Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...

随机推荐

  1. [01]从零开始学 ASP.NET Core 与 EntityFramework Core 课程介绍

    从零开始学 ASP.NET Core 与 EntityFramework Core 课程介绍 本文作者:梁桐铭- 微软最有价值专家(Microsoft MVP) 文章会随着版本进行更新,关注我获取最新 ...

  2. 【linux】linux命令lsof和grep命令的配合使用---linux根据端口查看PID,根据PID关键字高亮显示

    lsof命令,根据端口,查看进程PID lsof -i: ps命令+grep命令 --color参数,根据PID查看进程详情,高亮显示关键字 ps -ef | grep --color=always

  3. go-GUI-代码

    直接看网址吧,所有的GO-GUI代码!~~~~ 网址

  4. Python笔记:设计模式之工厂模式

    工厂模式:“工厂”即表示一个负责创建其他类型的对象的类,通常情况下,一个工厂的对象会有一个或多个方法与之关联,这些方法用于创建不同类型的对象,工厂对象会根据客户端给方法传递的不同的参数或者客户端调用不 ...

  5. 为什么要学 Python? python该怎么学

    很多童鞋对为什么学习Python感到迷茫,小编来跟大家说说学习Python的10个理由,希望可以帮助到大家!!! 摘要: 看完这十个理由,我决定买本python从入门到精通! 如果你定期关注现今的科技 ...

  6. [Go] golang实现mysql连接池

    golang中连接mysql数据库,需要使用一个第三方类库github.com/go-sql-driver/mysql,在这个类库中就实现了mysql的连接池,并且只需要设置两个参数就可以实现 一般连 ...

  7. Shell命令-网络操作之基础之ping、route

    文件及内容处理 - ping.route 1. ping:测试主机之间网络的连通性 ping命令的功能说明 ping 命令用于检测主机.执行 ping 指令会使用 ICMP 传输协议,发出要求回应的信 ...

  8. 运行java程序

    使用方式: java类名 硬盘上有HelloWorld.class,那么类名就是HelloWorld java HelloWorld[运行先到class路径下] 一定要注意:java命令后面跟的不是文 ...

  9. C# 深入分析 GC 处理机制

    引用地址:https://www.cnblogs.com/nele/p/5673215.html GC的前世与今生 虽然本文是以.NET作为目标来讲述GC,但是GC的概念并非才诞生不久.早在1958年 ...

  10. Centos 7 自动安装系统-pxe

    一.简介 PXE(Pre-boot Execution Environment,预启动执行环境)是由Intel公司开发的最新技术,工作于Client/Server的网络模式,支持工作站通过网络从远端服 ...