题目地址(02.07. 链表相交)

https://leetcode-cn.com/problems/intersection-of-two-linked-lists-lcci/

题目描述

  1. 给你两个单链表的头节点 headA headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null
  2. 图示两个链表在节点 c1 开始相交:
  3. 题目数据 保证 整个链式结构中不存在环。
  4. 注意,函数返回结果后,链表必须 保持其原始结构
  5. 示例 1
  6. 输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
  7. 输出:Intersected at '8'
  8. 解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
  9. 从各自的表头开始算起,链表 A [4,1,8,4,5],链表 B [5,0,1,8,4,5]。
  10. A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
  11. 示例 2
  12. 输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
  13. 输出:Intersected at '2'
  14. 解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
  15. 从各自的表头开始算起,链表 A [0,9,1,2,4],链表 B [3,2,4]。
  16. A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。
  17. 示例 3
  18. 输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
  19. 输出:null
  20. 解释:从各自的表头开始算起,链表 A [2,6,4],链表 B [1,5]。
  21. 由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA skipB 可以是任意值。
  22. 这两个链表不相交,因此返回 null
  23. 提示:
  24. listA 中节点数目为 m
  25. listB 中节点数目为 n
  26. 0 <= m, n <= 3 * 104
  27. 1 <= Node.val <= 105
  28. 0 <= skipA <= m
  29. 0 <= skipB <= n
  30. 如果 listA listB 没有交点,intersectVal 0
  31. 如果 listA listB 有交点,intersectVal == listA[skipA + 1] == listB[skipB + 1]
  32. 进阶:你能否设计一个时间复杂度 O(n) 、仅用 O(1) 内存的解决方案?

前置知识


公司

  • 暂无

思路

我们求出两个链表的长度,并求出两个链表长度的差值,然后让curA移动到,和curB 末尾对齐的位置
image.png
将两个列表的后端对其 然后依次往后遍历curab 如果相等就返回 不等就往后走

关键点

  • 简单来说,就是求两个链表交点节点的指针

代码

  • 语言支持:Java

Java Code:

  1. /**
  2. * Definition for singly-linked list.
  3. * public class ListNode {
  4. * int val;
  5. * ListNode next;
  6. * ListNode(int x) {
  7. * val = x;
  8. * next = null;
  9. * }
  10. * }
  11. */
  12. public class Solution {
  13. public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
  14. //定义curab两个节点
  15. ListNode curA = headA;
  16. ListNode curB = headB;
  17. //定义两个列表的长度
  18. int lenA = 0,lenB = 0;
  19. //求ab的len
  20. while (curA != null) {
  21. lenA++;
  22. curA = curA.next;
  23. }
  24. while (curB != null) {
  25. lenB++;
  26. curB = curB.next;
  27. }
  28. //将curab复位
  29. curA = headA;
  30. curB = headB;
  31. //如果B的长度大于a 交换ab的位置和长度
  32. if (lenB > lenA) {
  33. int tempLen = lenA;
  34. lenA = lenB;
  35. lenB = tempLen;
  36. ListNode tempCur = curA;
  37. curA = curB;
  38. curB = tempCur;
  39. }
  40. //ab len的长度
  41. int difference = lenA - lenB;
  42. //让a往前走差值的长度
  43. while (difference-- > 0) {
  44. curA = curA.next;
  45. }
  46. //当cura不等于空的时候 判断a是否等于b 如果等于 即找到了两个列表的交点
  47. //如果没找到 就让ab往前走一步
  48. while (curA != null) {
  49. if (curA == curB) {
  50. return curA;
  51. }
  52. curA = curA.next;
  53. curB = curB.next;
  54. }
  55. //如果最后都没有得到交点 返回null
  56. return null;
  57. }
  58. }

复杂度分析

令 n 为数组长度。

  • 时间复杂度:面试题 02.07. 链表相交 2 - 图2
  • 空间复杂度:面试题 02.07. 链表相交 2 - 图3#card=math&code=O%281%29&id=uI9cw)