160. Intersection of Two Linked Lists
题目
原始地址:https://leetcode.com/problems/intersection-of-two-linked-lists/#/description
/**
* 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) {
}
}
描述
给定两个相交的单链表,找出它们开始相交的节点。
分析
最直观的方法是先分别遍历两个链表,获得它们的长度lenA和lenB,然后让比较长的链表的指针向前移动lenA和lenB差值的个节点,之后顺序遍历,找到第一个相同的节点即可,见解法1。
另一种解法是循环遍历两个链表,当指针走到链表结尾时,再跳到另一个链表的头部,直到两个指针对应的节点相同。需要考虑的是如下两种情况:
- 两个链表长度相同。那么程序不会遍历两遍,当遇到交叉点或者走到结尾时(此时两个指针都是null),程序就会结束。
- 两个链表长度不同。那么当两个指针都遍历到第二个链表时,它们到链表结尾的距离是相同的,如果存在交叉点,那么这两个指针就能同时到达这个交叉点。详见解法2。
解法1
/**
* 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 a = headA, b = headB;
int lenA = 1, lenB = 1;
while (a.next != null) {
a = a.next;
lenA++;
}
while (b.next != null) {
b = b.next;
lenB++;
}
if (a != b) {
return null;
}
a = headA;
b = headB;
if (lenA > lenB) {
for (int i = 0; i < lenA - lenB; i++) {
a = a.next;
}
} else {
for (int i = 0; i < lenB - lenA; i++) {
b = b.next;
}
}
while (a != b && a != null) {
a = a.next;
b = b.next;
}
return a;
}
}
解法2
/**
* 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 a = headA, b = headB;
while (a != b) {
a = a == null ? headB : a.next;
b = b == null ? headA : b.next;
}
return a;
}
}