【LeetCode题解】160_相交链表

目录

  • 160_相交链表
    • 描述
    • 解法一:哈希表
      • 思路
      • Java 实现
      • Python 实现
    • 解法二:双指针(推荐)
      • 思路
      • Java 实现
      • Python 实现

160_相交链表

描述

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

例如,下面的两个链表

A:          a1 → a2↘c1 → c2 → c3↗            
B:     b1 → b2 → b3

在节点 c1 开始相交。

注意:

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

致谢:
特别感谢 @stellari 添加此问题并创建所有测试用例。

解法一:哈希表

思路

首先遍历链表 A 的所有节点,并将每个节点的引用存入哈希表中。接着,遍历链表 B 的每个节点,如果某个节点的引用在哈希表中存在,返回该节点的引用;如果遍历完链表 B 的所有节点没有发现这样一个节点,则返回 null

Java 实现

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode(int x) {*         val = x;*         next = null;*     }* }*/
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if (headA == null || headB == null) {return null;}Set<ListNode> nodes = new HashSet<>();ListNode temp = headA;while (temp != null) {nodes.add(temp);temp = temp.next;}temp = headB;while (temp != null) {if (nodes.contains(temp)) {return temp;}temp = temp.next;}return null;}
}

复杂度分析:

  • 时间复杂度:\(O(m+n)\),其中,\(m\) 表示链表 A 的节点数,\(n\) 表示链表 B 的节点数,最坏的情况下,需要遍历两个链表的所有节点
  • 空间复杂度:\(O(m)\) 或者 \(O(n)\)

Python 实现

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution(object):def getIntersectionNode(self, headA, headB):""":type head1, head1: ListNode:rtype: ListNode"""if not headA or not headB:return NonenodesA = set()curr = headAwhile curr:nodesA.add(curr)curr = curr.nextcurr = headBwhile curr:if curr in nodesA:return currcurr = curr.nextreturn None

复杂度分析同上。

解法二:双指针(推荐)

思路

双指针解法顾名思义需要两个指针,假设指针 pApB 分别指向链表 A 和链表 B 的头结点,之后两个指针分别以步幅为 1 的速度向链表的尾部遍历,当指针 pA 遍历到链表 A 的尾节点时,将指针 pA 指向链表 B 的头部。同样地,当指针 pB 遍历到链表 B 的尾节点时,将指针 pB 指向链表 A 的头部。当两个指针相遇时,指针 pA 或者 pB 所指向的节点就是两个链表的相交节点。

为了说明双指针的求解思路,假设链表 A 和链表 B 的结构如下图所示,

781387-20181026092833424-14763437.png

其中,链表 A 包含 6 个节点,节点的值分别为 1、3、5、7、9 和 11;链表 B 包含 4 个节点,节点的值分别为 2、4、9 和 11,因此,两个链表的相交节点为 9。设链表 A 中不相交的部分(即蓝色部分的节点)长度为 \(L1\),链表 B 中不相交的部分(即黄色部分的节点)长度为 \(L2\),两个链表相交的部分(即红色部分的节点)长度为 \(L3\)

如下图所示,当指针 pB 遍历到链表 B 的尾节点 11 时,指针 pA 遍历到链表 A 中节点 7 的位置,下一次遍历指针 pB 将处于链表 A 的节点 1 的位置。

781387-20181026092845833-659892497.png

同理,当指针 pA 遍历到链表 A 的尾节点 11 时,此时指针 pB 处于链表 A 中节点 3 的位置,下一次遍历指针 pA 将处于链表 B 的节点 2 位置。

781387-20181026092855618-184737944.png

再经过两次遍历后,指针 pA 将位于链表 B 中节点 4 的位置,而指针 pB 也将到达链表 A 的节点 4 的位置,下一次遍历两个指针将在节点 9(即相交节点)相遇。此时,两个指针走过的长度都为 \(L1 + L2 + L3\)。究其原因,可以将两个指针走过的“路程”看成 3 个部分,即蓝色部分、红色部分以及橙色部分,只是两个指针走过 3 个部分的顺序是不同的,指针 pA 先走蓝色部分而指针 pB 先走橙色部分,但是经过前 3 个部分后,两个指针走过的长度一定是相同的,因此在下一次遍历的时候两个指针一定会相遇。

781387-20181026092904638-1113805103.png

Java 实现

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode(int x) {*         val = x;*         next = null;*     }* }*/
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if (headA == null || headB == null) {return null;}ListNode pA = headA;ListNode pB = headB;while (pA != pB) {pA = pA == null ? headB : pA.next;pB = pB == null ? headA : pB.next;}return pA;}
}

复杂度分析:

  • 时间复杂度:\(O(L1 + L2 + L3) = O(n)\),如果两个链表存在相交节点,则经过 \(L1 + L2 + L3\) 的“长度”后,两个指针一定会相遇
  • 空间复杂度:\(O(1)\),只需要保存两个引用

Python 实现

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution(object):def getIntersectionNode(self, headA, headB):""":type head1, head1: ListNode:rtype: ListNode"""if not headA or not headB:return Nonep_a, p_b = headA, headBwhile p_a != p_b:if p_a:p_a = p_a.nextelse:p_a = headBif p_b:p_b = p_b.nextelse:p_b = headAreturn p_a

复杂度分析同上。

转载于:https://www.cnblogs.com/xugenpeng/p/9854538.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/365230.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

maya崩溃自动保存路径_maya 使用swig将插件编译成pyd,无缝使用内置数据实现加速计算模块...

前言&#xff1a;原本目的是想寻求一种方式来对cpu计算密集型代码部分进行加速替代&#xff0c;但是maya中mll插件的插件套路在传递参数上会占用大量的io&#xff0c;对于数据比较大的部分也会有相当消耗。如果全部写在c部分又感觉缺乏灵活性&#xff0c;所以琢磨的一种可以在p…

Slip.js – 在触摸屏上实现 Swipe 对列表重新排序

Slip.js 是一个很小的 JavaScript 库&#xff0c;用于实现对触摸屏的互动 Swipe 和对元素重新排序列表&#xff08;Reordering&#xff09;。Slip.js 没有任何的依赖&#xff0c;你可以通过自定义 DOM 事件实现重新排序交互。 您可能感兴趣的相关文章Pace.js – 页面加载进度自…

构建和运行Java 8支持

尚未提供对Java 8的Eclipse支持。 如果要使用它&#xff0c;则必须构建它。 Eclipsepedia的JDT Core / Java8页面包含有关使用Eclipse Java开发工具 &#xff08;JDT&#xff09;中不断发展的Java 8支持源来设置开发环境的说明。 说明中缺少一些内容&#xff1b; 待会儿我会回圈…

狄克斯特拉 Dijkstra 算法 C#实现

今天在看《算法图解》&#xff0c;看了加权最小路径算法&#xff0c;决定用代码实现一下。 首先是画有向图&#xff0c;在网上找了一下&#xff0c;有不错的开源软件graphviz,该源代码托管在GitLab上。该软件是一个图形可视化软件。 画了一个有向图如下&#xff1a; 画图用的代…

So Easy! 让开发人员更轻松的工具和资源

这篇文章给大家分享让开发人员生活更轻松的免费工具和资源。所以&#xff0c;如果你正在寻找一些为迅速解决每天碰到的设计和开发问题的工具和资源&#xff0c;不要再观望&#xff0c;试试这些工具吧。这些奇妙的工具不仅会加快您的生产&#xff0c;也让你的工作质量提升。 您可…

android linux截图库,Android中截图(surfaceView)源码

总结了一个方法&#xff0c;实现了在Android当前Activity的截图&#xff0c;本人测试确实通过了&#xff0c;不过有朋友说截出来的图是黑色的&#xff0c;不能看。我心想&#xff0c;这没有问题啊&#xff0c;相同的代码我就可以执行通过&#xff0c;并没有没有在意这个问题。可…

23套新鲜出炉的网站和手机界面 PSD 素材

Web 用户界面&#xff0c;移动用户界面和线框套件对设计师很有用&#xff0c;因为这些套件让他们使用快速和有效的方式复制用户界面。这些类型的工具包提供了一个基本的用户界面元素&#xff0c;用于它们需要制作的网站或软件模型。 在这篇文章中&#xff0c;我们展示的是自由和…

arcgis栅格邻域统计_ArcGIS 从基础到实战书正式出版,易智瑞技术总裁沙志友沙总推荐并亲自写序...

《ArcGIS 从基础到实战》书正式出版&#xff0c;易智瑞技术总裁沙志友沙总推荐并亲自写序&#xff0c;京东地址 https://item.jd.com/10025512034581.html第一章 ArcGIS基础和入门 11.1 ArcGIS 10.7 Desktop的安装 11.1.1 安装环境 11.1.2 安装步骤 21.1.3 注意的问…

WebLogic Classloader分析工具

WebLogic Server具有一个名为Classloader Analysis Tool的内置Web应用程序&#xff0c;您可以通过http&#xff1a;// localhost&#xff1a;7001 / wls-cat访问它 您需要使用为/ console Webapp配置的同一用户登录。 使用CAT&#xff0c;您可以检查应用程序在服务器中加载了哪…

Maplace.js – 小巧实用的 jQuery 谷歌地图插件

Maplace.js是一个小的显示谷歌地图的 jQuery 插件&#xff0c;帮助你把谷歌地图嵌入到你的网站&#xff0c;快速在地图位置上创建标记和控制菜单。它需要 jQuery 和谷歌地图 API v3 支持&#xff0c;所以这两个都需要引入到你的页面。它支持标记和自定义图标、缩放级别和自定义…

使用Spring Roo进行概念验证

在Keyhole期间&#xff0c;我参与了许多项目&#xff0c;其中客户要求我们重写旧系统&#xff0c;同时保留其现有数据库。 有时&#xff0c;它有助于快速演示如何使用当前技术来简化开发&#xff0c;测试和维护其代码。 我发现可以创建一个快速示例&#xff08;与当前项目相关…

z490 linux raid,华硕z490主板装win7系统及bios设置教程(支持10代usb驱动)

[文章导读]我们在组装电脑时&#xff0c;华硕主板可能是大家的首选&#xff0c;最近有网友问&#xff0c;我组装的华硕z490主板电脑怎么装win7系统呢&#xff0c;这里和大家说下&#xff0c;从华硕z490主板后默认是uefigpt引导模式&#xff0c;且官方没有出usb驱动&#xff0c;…

Ember Charts – 基于 Ember D3 的图表库

Ember Charts 是一个基于 Ember.js 和 D3.js 的图表库。它包括时间序列、柱状图、饼图、点图&#xff0c;很容易扩展和修改。这些图表组件代表图表交互性和演示的最佳实践&#xff0c;是高度可定制和可扩展的。您可以添加说明、标签、提示和鼠标悬停效果。 您可能感兴趣的相关文…

值得拥有!精心推荐几款超实用的 CSS 开发工具

当你开发一个网站或 Web 应用程序的时候&#xff0c;有合适的工具&#xff0c;绝对可以帮助您节省大量的时间。在这篇文章中&#xff0c;我为大家收集了超有用的 CSS 开发工具。 对于 Web 开发人员来说&#xff0c;找到有用的 CSS 开发工具&#xff0c;就像找到一个魔灯&#x…

matplotlib散点图笔记

定义: 由一组不连续的点完成的图形 散点图: 包含正相关性,负相关性和不相关性. 散点图生成函数: plt.scatter(x,y) 演示代码如下: import numpy as np import matplotlib.pyplot as plt open,closenp.loadtxt(‘000001.txt’,delimiter’,’,skiprows1,usecols(1,4),unpackTrue…

20款漂亮的长阴影 LOGO 设计作品【附免费生成工具】

长阴影&#xff08;Long Shadow&#xff09;概念来自于最新非常流行的扁平化设计&#xff08;Flat Design&#xff09;。扁平化设计趋势影响最大的是用户界面元素和图标&#xff0c;但它也开始蔓延到其他网页设计的其他部分。 长阴影其实就是扩展了对象的投影&#xff0c;感觉是…

c语言sqlist结构体,c语言里 sqlist

满意答案cielkong2018.08.12采纳率&#xff1a;43% 等级&#xff1a;9已帮助&#xff1a;463人c语言里 sqlist&#xff1f;//定义顺序表L的结构体typedef struct{Elemtype data[MaxSize]&#xff1b;int length;}SqList;//建立顺序表void CreateList(SqList * &L,ElemTy…

汇编语言实验三

1. 练习1 第1步&#xff0c;编写汇编源程序t1.asm, 源程序代码如图1-1所示。 (1) 运行程序&#xff0c;观察程序输出结果是什么&#xff1f; 2) 将 line4和line9种寄存器dl 的值分别修改为 0~9 中任何一个数字&#xff0c;重新汇编→ 连接→运行&#xff0c;观察结果的变化。 …

Java事实让您大吃一惊! (信息图)

随着Java 8计划在未来几天内发布 &#xff0c;我们正在寻找一些Java事实&#xff0c;这些事实将真正捕捉这种编程语言对世界的影响。 因此&#xff0c;我们决定创建一个简单的图表&#xff0c;描述有关Java历史的一些重要统计数据。 信息的主要来源是Oracle的Java时间轴 。 我…

15个创意示例教您如何自定义 404 错误页面

在这篇文章中&#xff0c;你会看到一组充满创意的404错误页面设计。我希望这个集合能够启发和帮助你设计自己的 404 错误页面。一个自定义的404错误页面将鼓励用户在您的网站上停留更长的时间。 404页面必须让访客容易理解&#xff0c;最好有有一些互动。你会看到下面的例子中一…