首页 > 其他分享 >面试题 02.07. 链表相交

面试题 02.07. 链表相交

时间:2023-12-16 19:55:36浏览次数:39  
标签:面试题 ListNode 02.07 链表 virtualB virtualA headB null

题目

面试题 02.07. 链表相交

要求

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。

思路和答案

这道题目先用暴力破解,直接使用双层 for 循环,如下:

/**
 * 暴力破解,双层 for 循环
 *
 * @param headA
 * @param headB
 * @return
 */
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    ListNode virtualA = headA;
    while (virtualA != null) {
        ListNode virtualB = headB;
        while (virtualB != null) {
            if (virtualB == virtualA) {
                return virtualA;
            }
            virtualB = virtualB.next;
        }
        virtualA = virtualA.next;
    }
    return null;
}

想一想有没有比这个更好的解决方案呢,可以考虑使用集合呀,Set 和 List 都可以,遍历一个链表,放入集合,遍历另外一个链表,判断是否包含在内,如下:

/**
 * 单层循环,借助 List 结构
 *
 * @param headA
 * @param headB
 * @return
 */
public ListNode getIntersectionNode2(ListNode headA, ListNode headB) {
    ListNode virtualA = headA;
    ListNode virtualB = headB;
    List<ListNode> listA = new ArrayList<>();
    while (virtualA != null) {
        listA.add(virtualA);
        virtualA = virtualA.next;
    }
    while (virtualB != null) {
        if (listA.contains(virtualB)) {
            return virtualB;
        }
        virtualB = virtualB.next;
    }
    return null;
}

上面两个题目前者的时间复杂度是 O(m * n),空间复杂度O(1);后者的时间复杂度为O(m + n),空间复杂度为 O(m),用空间换取时间了,这个解决方案在 leetcode 上执行慢的原因在于listA.contains 消耗时间,contains 底层也是通过 for 循环遍历的,所以这里使用 HashMap 替换 List,可以提高性能,如下:

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    ListNode virtualA = headA;
    ListNode virtualB = headB;
    HashMap<ListNode, Integer> map = new HashMap<>();
    while (virtualA != null) {
        map.put(virtualA, virtualA.val);
        virtualA = virtualA.next;
    }
    while (virtualB != null) {
        if (map.get(virtualB) != null) {
            return virtualB;
        }
        virtualB = virtualB.next;
    }
    return null;
}

接下来说说双指针,想到用双指针,但是没想到怎么用,就是在处理指针如果遍历到链表的结尾应该怎么处理,看了题解之后发现,还可以在指针遍历到链表结尾之后转去遍历另外一个链表,举个简单的例子,链表 A 为 1→2→3→4→null,链表 B 为 5→6→7→8→3→4→null,这个时候指针 C 遍历列表 A,指针 D 遍历列表 B,当 C 遍历到 A 的尾部之后转去遍历链表 B,D 遍历到 B 的结尾之后转去遍历 A,这样下次 C 和 D 遍历的实际链表分别为:

1→2→3→4→5→6→7→8→3→4→null

5→6→7→8→3→4→1→2→3→4→null

上下对比一下就知道结果了,那代码怎么写呢?如下:

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    ListNode pointA = headA;
    ListNode pointB = headB;
    boolean ab = true;
    boolean ba = true;
    while (pointA != null && pointB != null) {
        if (pointA == pointB) {
            return pointA;
        }
        pointA = pointA.next;
        pointB = pointB.next;
				// 声明 ab 和 ba 的目的是为了防止死循环
        if (pointA == null && ab) {
            pointA = headB;
            ab = false;
        }
        if (pointB == null && ba) {
            pointB = headA;
            ba = false;
        }
    }
    return null;
}

标签:面试题,ListNode,02.07,链表,virtualB,virtualA,headB,null
From: https://www.cnblogs.com/wadmwz/p/17907241.html

相关文章

  • 19.删除链表的倒数第N个节点
    题目19.删除链表的倒数第N个节点要求给你一个链表,删除链表的倒数第n个结点,并且返回链表的头结点。答案先看看直接思路,首先遍历一遍,计算出元素的个数,之后计算出正向遍历要删除的元素,注意的是要创建一个虚拟节点,目的是可能删除头节点,如果删除头节点,没有虚拟节点,不易删除,当然......
  • 24. 两两交换链表中的节点
    题目24.两两交换链表中的节点要求给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。解答迭代的思路就是考虑清楚下一个节点是什么,举个实际的例子来解释代码,1→2→3→4→null,首先我先确定了最后......
  • 2023最新高级难度CSS3面试题,包含答案。刷题必备!记录一下。
    好记性不如烂笔头内容来自面试宝典-高级难度CSS3面试题合集问:解释一下CSS3中的动画关键帧(@keyframes)和它们是如何工作的。CSS3中的动画关键帧(@keyframes)是一个强大的特性,它允许开发者创建复杂的动画效果。通过定义一组关键帧,可以控制元素在动画过程中的不同状态。工作原......
  • 力扣141-环形链表
    难度:【简单】第一遍:用最朴素的算法写,一个HashSet保存访问过的节点,但是仅保存了节点的value,出现值相等的节点算法就会失效。提交后当然是“解答错误”。第二遍:修改HashSet数据类型,重新提交后显示“通过”。第三遍:优化空间复杂度到O(1)。没有思路就参考了官方题解,使用了快慢指针......
  • 2023最新中级难度CSS3面试题,包含答案。刷题必备!记录一下。
    好记性不如烂笔头内容来自面试宝典-中级难度CSS3面试题合集问:描述一下你对CSS盒模型的理解。CSS盒模型是一种用于描述元素布局和大小的方式。在HTML中,每个元素都可以看作是一个矩形框,这个框由内容(content)、填充(padding)、边框(border)和外边距(margin)组成。内容(Content):这......
  • 代码随想录算法训练营第三天|203.移除链表元素、707.设计链表、206.反转链表
    LeetCode 203.移除链表元素题目链接:203.移除链表元素原链表删除元素(需要区分头节点和非头结点)使用虚拟头节点,统一链表操作(注意:新链表头结点是虚拟头节点的下一节点) LetCode707.设计链表题目链接:707.设计链表注意:头节点采用虚拟头节点,使得链表操作具有一致性!!!单链......
  • 算法学习Day3虚拟头指针,设计链表,反转链表
    Day3虚拟头指针,设计链表,反转链表ByHQWQF2023/12/15笔记203.移除链表元素给你一个链表的头节点head和一个整数val,请你删除链表中所有满足Node.val==val的节点,并返回新的头节点。解法:虚拟头指针看起来非常简单,但是由于如果直接对原始的链表进行操作,如果头节点的v......
  • 代码随想录算法训练营第三天 | 链表理论基础,203.移除链表元素,707.设计链表,206.反转链
    一、链表理论基础学习:1.链表定义线性表的一种存储方式,在逻辑上连续的数据在物理存储中可以不连续。classListNode{intval;ListNodenext;ListNode(){}ListNode(intval){this.val=val;this.next=null;}ListN......
  • 代码随想录算法训练营Day3 | 203.移除链表元素、707.设计链表、206.翻转链表
    这三道题都不涉及什么难以理解的算法,是对链表基础知识的一个复习巩固对于有数据结构基础的同学来说这个没有什么难度但是,写代码的过程中,我明显感觉到,我需要更加完善和统一的代码风格,作为一个前OIer,我的c和cpp混用的情况在基础数据结构的封装层面造成了不小的混乱!我需要去补充c......
  • 2023最新高级难度HTML面试题,包含答案。刷题必备!记录一下。
    好记性不如烂笔头内容来自面试宝典-高级难度HTML面试题合集问:请深入解释HTML5的设计理念和它相比于之前版本的重要改进。HTML5的设计理念主要围绕以下几个方面:更强的可扩展性:HTML5引入了大量的新元素和属性,增强了文档结构和语义化能力,使得开发者能够更加方便地编写和维......