160.相交链表
问题:给你两个单链表的头节点 headA
和 headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null
思路:
- 首先想到的是借助list存储遍历过的节点,无论遍历到哪个链表的节点都取list中查找,若存在,则说明交点就是当前节点。正确思路应该是先遍历一条链表,将节点存入list,然后再遍历另一条链表,遍历过程查看list中是否存在这个节点
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) {
return null;
}
if(headB == headA) return headA;
List<ListNode> list = new LinkedList<>();
while(headA != null || headB != null){
if (headA != null) {
if (list.contains(headA)) return headA;
list.add(headA);
headA = headA.next;
}
if (headB == null) return null;
if (list.contains(headB)) return headB;
list.add(headB);
headB = headB.next;
}
return null;
}
}
//正解
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
Set<ListNode> visited = new HashSet<ListNode>();
ListNode temp = headA;
while (temp != null) {
visited.add(temp);
temp = temp.next;
}
temp = headB;
while (temp != null) {
if (visited.contains(temp)) {
return temp;
}
temp = temp.next;
}
return null;
}
}
- 双指针:
使用双指针的方法,可以将空间复杂度降至O(1)。
只有当链表headA 和headB 都不为空时,两个链表才可能相交。因此首先判断链表headA 和headB 是否为空,如果其中至少有一个链表为空,则两个链表一定不相交,返回null。
当链表 headA 和headB 都不为空时,创建两个指针pA 和 pB,初始时分别指向两个链表的头节点headA 和 headB,然后将两个指针依次遍历两个链表的每个节点。具体做法如下:
每步操作需要同时更新指针 pA 和 pB。
如果指针pA 不为空,则将指针 pA 移到下一个节点;如果指针 pB 不为空,则将指针pB 移到下一个节点。
如果指针 pA 为空,则将指针pA 移到链表headB 的头节点;如果指针pB 为空,则将指针pB 移到链表headA 的头节点。
当指针 pA 和 pB 指向同一个节点或者都为空时,返回它们指向的节点或者null。
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) {
return null;
}
ListNode pA = headA, pB = headB;
while (pA != pB) {
pA = pA == null ? headB : pA.next;
pB = pB == null ? headA : pB.next;
}
return pA;
}
}
整理思路,记录博客,以便复习。若有误,望指正~