题目描述
给你两个单链表的头节点 headA
和 headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null
。
示例:
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 输出:Intersected at '8' 解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。 从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。 在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
题目分析
解法一:利用双指针进行遍历,当两个节点不相同时,每个指针指向下一个节点,当其中一个指针为空时,此指针返回到另一个节点的头部。这样当每一个指针遍历一次链表时,指针的指向位置就为两个链表的对立位置。继续循环,当两个指针相等时返回。
解法二:解法二相对来说比较容易理解。首先获取两个链表的长度,当链表B长度大于链表A时,将链表A与链表B的长度与头节点进行交换(如果不进行交换,后续循环会有两种类型)。当链表A的长度大于等于链表B的长度时就不需要交换。
此时经过判断之后,链表A为长链表。获取两个链表的差值,循环A链表,循环过后curA与curB为对立位置。循环,当curA == curB时,返回curA。
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) {
ListNode A = headA, B = headB;
while (A != B) {
A = A != null ? A.next : headB;
B = B != null ? B.next : headA;
}
return A;
}
}
解法二:
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
int lenA = 0,lenB = 0;
//获取A链表长度
while(curA != null){
lenA++;
curA = curA.next;
}
//获取B链表长度
while(curB != null){
lenB++;
curB = curB.next;
}
curA = headA;
curB = headB;
//交换操作
if(lenB > lenA){
int tmpLen = lenA;
lenA = lenB;
lenB = tmpLen;
ListNode tmpNode = curA;
curA = curB;
curB = tmpNode;
}
int gap = lenA - lenB;
//将curA移动到curB的对立位置
while(gap-- > 0){
curA = curA.next;
}
//循环操作
while(curA != null){
if(curA == curB){
return curA;
}
curA = curA.next;
curB = curB.next;
}
return null;
}
}