输入两个链表,找出它们的第一个公共节点。
方法一:利用哈希表
思路:将其中一条链表的所有值都添加到哈希表中,然后遍历另一条链表b,每获取到b链表中的一个节点,就判断哈希表中是否存在这个节点,如果存在,那么就说明当前这个节点就是相交的第一个公共节点,将其返回,如果将链表b都遍历完了,都没有找到公共的节点,说明两条链表没有相交部分,因此返回null。
对应的代码:
/**
* 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;//如果两个链表中至少一个为空,那么两个链表必定不会相交,返回null
/*
两个链表相交,说明在相交的地方,两个声明的地址是相同的,所以是
headA == headB,而不应该是headA.val == headB.val,可能会存在地
址不同,但是值相同,但是由于地址不同,所以两个链表是不相交的
*/
if(headA == headB)
return headA;
HashMap<ListNode,Boolean> map = new HashMap<ListNode,Boolean>();
while(headA != null){
//将链表A的所有节点添加到哈希表中
map.put(headA,true);
headA = headA.next;
}
while(headB != null){
/*
遍历链表B,然后判断哈希表中是否存在链表B上的节点,如果存在,那么就
表示这个顶点是相交的第一个节点,直接将其返回,当链表B遍历完毕退出
循环事,表示两个链表不相交,直接返回null
*/
if(map.containsKey(headB))
return headB;
headB = headB.next;
}
return null;//如果两个链表中至少一个为空,那么说明不相交
}
}
运行结果:
方法二:利用双指针
对应的代码:
/**
* 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 == B的时候存在两种可能,一种是A = B = null退出循环,此时
说明两个链表是不相交的,否则,如果A = B != null,说明两个链表
相交,返回的就是相交的第一个节点
*/
A = A == null ? headB : A.next;//如果A不是最后一个节点那么继续遍历a链表,否则回到b链表进行遍历
B = B == null ? headA : B.next;//如果B不为空,那么就继续遍历b链表,否则回到a链表进行遍历
/*
这样写是错误的,因为如果当前A、B中有一个为null,另一个不为
null,那么就会发生报错,因为null.next发生错了,提示
NullPointerExceptiong(如果两个链表都不为空的情况下是正常的,
但是存在一开始有一个链表为空的情况,这时候就会抛出
NullPointerException异常,同时也会存在超时的情况,比如一个链
表[2,6,4],链表b为[1,5],运行超时)
A = A.next == null ? headB : A.next;
B = B.next == null ? headA : B.next;
*/
}
return A;
}
}
运行结果: