思路–暴力–时间复杂度O(nm)
,原因是嵌套循环
直接两个循环,找到第一个相同的位置,就返回。注意,要使用equals
而不是==
,因为i
和j
的类型是ListNode
,此时的==
比较的是内存地址,而equals
比较的是内容。
代码
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
for (ListNode i = headA;i!=null;i = i.next)
for (ListNode j = headB;j!=null;j = j.next)
if (i.val == j.val)
return i;
return null;
}
思路2–哈希set或哈希map
因为数据保证不会出现环,所以两个链表要么不相交,要么相交后,后续节点的值一定相等。所以可以使用判断“子集”
的方法来做。
把headA的顺序子集
放在哈希set或map中,然后根据headB的顺序子集进行判断,如果出现相等的子集,则返回,否则就返回null。
代码
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
Set<ListNode> set = new HashSet<>();
while (headA!= null){
set.add(headA);
headA = headA.next;
}
while(headB!=null)
{
if (set.contains(headB))
return headB;
headB = headB.next;
}
return null;
}
}
思路3–差值法 来自leetcode–宫水三叶 时间复杂度O(n+m)
原因是只有
根据大佬的代码,自己的一点理解:因为数据保证不会出现环,也就表示只要出现相等的情况,后续的数据都是相等的,因此,如果A长度为a,B长度为b
,且a>b
,那么在A的前a-b个元素
中,一定不存在和B相等的情况,因此可以先把前面“多余”
的部分先处理掉,然后进行比较。
因为此时两个链表的长度相同,因此一旦相同,剩余的均相同;对应元素不相同的话,两个链表应该均向后next
,否则的话就不满足相等元素个数相等这一条件,因此使用了while
,而不是暴力方法的for
。
代码
public class Solution {
public ListNode getIntersectionNode(ListNode a, ListNode b) {
int c1 = 0, c2 = 0;
ListNode t1 = a, t2 = b;
while (t1 != null && ++c1 > 0) t1 = t1.next;
while (t2 != null && ++c2 > 0) t2 = t2.next;
int t = Math.abs(c1 - c2);
while (t-- > 0) {
if (c1 > c2) a = a.next;
else b = b.next;
}
while (a != null && b != null) {
if (a.equals(b)) {
return a;
} else {
a = a.next;
b = b.next;
}
}
return null;
}
}