题目
链接:https://leetcode.cn/problems/intersection-of-two-linked-lists/description/?envType=study-plan-v2&envId=top-100-liked
两链表相交,节点从是否相交来分类,其实就是两种一种是有共同节点,一种是没有共同节点;
其实看到这题我最先想到的做法,就是在链表中维护一个计数器,然后遍历两个链表,当便利到某个节点计数器 + 1 等于2时,就进行返回;
但题目说了不能改变其数据结构
题解一
Hash
遍历第一个链表时,存储每个节点到hash表
遍历第二个链表时,判断当前节点是否在hash表中存在,顺序遍历,第一个存在于
hash表的节点就是相交的节点
代码实现
public class LinkedIntersection {
/**
* 链表相交
*/
// Definition for singly-linked list.
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
Set<ListNode> visited = new HashSet<>();
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(n)
空间复杂度 : O(n)
题解二
双指针
设链表1长度为a,链表2长度为b,链表相交长度为c
则a + (b-c) = b + (a-c)
a + b - c = b + a - c, 且c可能为0
现在有两个指针,
指针A遍历完链表1后遍历链表2
指针B遍历完链表2后遍历链表1
我们可以通过两种情况分析:
1、两链表相交
指针A遍历完链表1后遍历链表2
指针B遍历完链表2后遍历链表1
两节点会在相交点重合
2、未相交
则代表指针A遍历完链表1后遍历链表2
指针B遍历完链表2后遍历链表1
两指针最后结果都为null
,则代码如下
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode nodeA = headA, nodeB = headB;
while (nodeA != nodeB){
nodeA = nodeA != null ? nodeA.next : headB;
nodeB = nodeB != null ? nodeB.next : headA;
}
return nodeA;
}
```
时间复杂度 :O(C)
空间复杂度 : O(1)