题目
题解一:set 哈希集合
- 采用set集合的去重特性,先遍历A表,再遍历B表的同时判断是否有相同的链表节点(两条链表里面虽然有元素相同,但是不是同一对象,但是相交的链表节点肯定是同一个对象,相同对象在add的时候会返回false
/**
* set集合去重方法
* @param headA
* @param headB
* @return
*/
public static ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB ==null) {
return null;
}
Set<ListNode> listNodeSet = new HashSet<>();
//遍历A表
while(headA != null){
listNodeSet.add(headA);
headA = headA.next;
}
//遍历B表 并且同时判断是否存在重复元素
while (headB != null){
boolean addBoolean = listNodeSet.add(headB);
if (!addBoolean) {
return headB;
}
headB = headB.next;
}
//B表能循环到null,代表两个链表没有相交
return null;
}
题解二:双指针解法
这是一个不容易想出来的方法:因为两个链表有长有短,那么只要两个链表在走完自己的链表之后,再去另一个链表的头走起,一直走下去,若两个链表指针相遇了,相遇的这个节点就是两个链表相交的共同值。
定义两个指针, 第一轮让两个到达末尾的节点指向另一个链表的头部, 最后如果相遇则为交点(在第一轮移动中恰好抹除了长度差)
两个指针等于移动了相同的距离, 有交点就返回, 无交点就是各走了两条指针的长度
/**
* 双指针法
*
* @param headA
* @param headB
* @return
*/
public static ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) {
return null;
}
//设置A 和 B 的开始链表指针 Pa 和 Pb
ListNode Pa = headA;
ListNode Pb = headB;
//遍历同样的步数
while (Pa!= Pb){//不论是走到的相等或者最后为null都结束循环
//若pa遍历完了A链表则去遍历B 链表
if (Pa == null) {
Pa = headB;
}else {
//遍历
Pa = Pa.next;
}
//若pb遍历完了B链表则去遍历A 链表
if (Pb == null) {
Pb = headA;
}else {
//遍历
Pb = Pb.next;
}
}
return Pa;
}