11_160. 相交链表
题目描述:
解题思路:
- 想到了之前考研时候做过的一道题,如果链表相交,那么自相交节点开始,后面的序列是相同的。因此可以通过遍历两个链表,得到链表长度,获得链表长度差k。然后让长链表先遍历k步,再同时遍历两个链表,如果遍历到相交节点,则两个节点是同一个,如果不是相交链表,等遍历结束时,该节点是null。
- 哈希表:将链表A添加到Hash表中,然后依次遍历链表B,如果链表B的节点存在于链表A的节点,那么表示相交。
- 双指针:两个指针都从头开始同时遍历,假设两个链表分别为m,n,A链表相交前的部分是a,B链表是b,相交后的部分是c;如果两个链表长度相同,如果有相交,则直接返回相同的节点即可,如果不相交,则遍历到空值;如果两个链表长度不同,那么当链表A遍历到结束后,从链表B开始遍历,链表B结束后,从A遍历,如果相交,那么当A再到交点的时候是a+c+b,而B恰好也是b+c+a;如果不相交,那么两者节点不相同。
注意:并不会出现相交后在分离的情形,因为相交必然是同一个节点,如果分离,需要有两个next
代码:
先消除长度差,同时双指针遍历
//先消除长度差,同时双指针遍历
/**
* 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;
}
int aLen = 0;
int bLen = 0;
ListNode listA = headA;
ListNode listB = headB;
while (listA != null || listB != null){
if (listA == null){
bLen++;
listB = listB.next;
}else if (listB == null){
aLen++;
listA = listA.next;
}else{
aLen++;
bLen++;
listA = listA.next;
listB = listB.next;
}
}
int k = Math.abs(aLen - bLen);
listA = headA;
listB = headB;
for (int i = 0;i < k;i++){
if (aLen >= bLen){
listA = listA.next;
}else{
listB = listB.next;
}
}
while(listA != null){
if (listA == listB ){
return listA;
}
listA = listA.next;
listB = listB.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) {
//哈希表
HashSet visited = new HashSet<>();
ListNode pA = headA;
while (pA != null){
visited.add(pA);
pA = pA.next;
}
pA = headB;
while (pA != null){
if (visited.contains(pA)){
return pA;
}
pA = pA.next;
}
return null;
}
}
双指针 a+c+b = b+c+a
//双指针 a+c+b = b+c+a
/**
* 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 pA = headA;
ListNode pB = headB;
while (pA != pB){
pA = pA == null ? headB : pA.next;
pB = pB == null ? headA : pB.next;
}
return pA;
}
}