程序员面试金典(第 6 版)

面试题 02.07. 链表相交

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


思路:

  • 交点不是数值相等,而是指针相等
  • 如果两个单链表有交点,则交点及后半部分是重合的
  • 先求出两个链表的长度,并求出两个链表长度的差值
  • 通过差值,让两个指针移动到两个链表末尾对齐的位置,如下所示。并依次比较
  • 图片.png

  1. public class Solution {
  2. public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
  3. ListNode curA = headA;
  4. ListNode curB = headB;
  5. // 两个链表的长度
  6. int lengthA = 0;
  7. int lengthB = 0;
  8. // 求出两个链表的长度
  9. while (curA != null) {
  10. lengthA++;
  11. curA = curA.next;
  12. }
  13. while (curB != null) {
  14. lengthB++;
  15. curB = curB.next;
  16. }
  17. curA = headA;
  18. curB = headB;
  19. // 让 headA、curA 为最长的那个链表
  20. if (lengthB > lengthA) {
  21. int tempLength = lengthA;
  22. lengthA = lengthB;
  23. lengthB = tempLength;
  24. ListNode tempNode = curA;
  25. curA = curB;
  26. curB = tempNode;
  27. }
  28. int gap = lengthA - lengthB;
  29. // 让 curA 和 curB 在同一起点上(末尾位置对齐)
  30. while (gap-- > 0) {
  31. curA = curA.next;
  32. }
  33. // 遍历 curA 和 curB,遇到相同节点则返回
  34. while (curA != null) {
  35. if (curA == curB) {
  36. return curA;
  37. } else {
  38. curA = curA.next;
  39. curB = curB.next;
  40. }
  41. }
  42. return null;
  43. }
  44. }