题目描述
给定两个(单向)链表,判定它们是否相交并返回交点。请注意相交的定义基于节点的引用,而不是基于节点的值。换句话说,如果一个链表的第k个节点与另一个链表的第j个节点是同一节点(引用完全相同),则这两个链表相交。
题目分析
如果说引用相同,那么next值也相同,所以两个相交链表是这个样子的
最简单的方法,暴力o(n^2)
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
while(curA!=null){
curB = headB;
while(curB!=null){
if(curB == curA){
return curB;
}
curB = curB.next;
}
curA = curA.next;
}
return null;
}
}
暴力优化,使用set。代码禁忌,禁止while循环里套用while。
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
//创建集合set
Set<ListNode> set = new HashSet<>();
//先把链表A的结点全部存放到集合set中
while (headA != null) {
set.add(headA);
headA = headA.next;
}
//然后访问链表B的结点,判断集合中是否包含链表B的结点,如果包含就直接返回
while (headB != null) {
if (set.contains(headB))
return headB;
headB = headB.next;
}
//如果集合set不包含链表B的任何一个结点,说明他们没有交点,直接返回null
return null;
}
2,先统计两个链表的长度
还可以先统计两个链表的长度,如果两个链表的长度不一样,就让链表长的先走,直到两个链表长度一样,这个时候两个链表再同时每次往后移一步,看节点是否一样,如果有相等的,说明这个相等的节点就是两链表的交点,否则如果走完了还没有找到相等的节点,说明他们没有交点,直接返回null即可,来画个图看一下。
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
//统计链表A和链表B的长度
int lenA = length(headA), lenB = length(headB);
//如果节点长度不一样,节点多的先走,直到他们的长度一样为止
while (lenA != lenB) {
if (lenA > lenB) {
//如果链表A长,那么链表A先走
headA = headA.next;
lenA--;
} else {
//如果链表B长,那么链表B先走
headB = headB.next;
lenB--;
}
}
//然后开始比较,如果他俩不相等就一直往下走
while (headA != headB) {
headA = headA.next;
headB = headB.next;
}
//走到最后,最终会有两种可能,一种是headA为空,
//也就是说他们俩不相交。还有一种可能就是headA
//不为空,也就是说headA就是他们的交点
return headA;
}
//统计链表的长度
private int length(ListNode node) {
int length = 0;
while (node != null) {
node = node.next;
length++;
}
return length;
}
优化,双指针,根据路径长度来算是否有相交节点。
如果有相交的结点D的话,每条链的头结点先走完自己的链表长度,然后回头走另外的一条链表,那么两结点一定为相交于D点,因为这时每个头结点走的距离是一样的,都是 AD + BD + DC,而他们每次又都是前进1,所以距离相同,速度又相同,固然一定会在相同的时间走到相同的结点上,即D点,当然,如果没有相交,那么就为null,每个指针都走了链表A和链表B,长度相同,所以就为null。
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
while(curA!=curB){
if(curA==null){
curA = headB;
}else{
curA = curA.next;
}
if(curB==null){
curB= headA;
}else{
curB = curB.next;
}
}
return curA;
}
}