题目链接:
https://leetcode.cn/problems/intersection-of-two-linked-lists/
进阶:你能否设计一个时间复杂度 O(m + n) 、仅用 O(1) 内存的解决方案?
方案一:
解题思路:
- 题中说到不能通过节点的值是否相等来判断,这一点很明显是想判断引用的对象是否为同一个
- 对于单向链表结构,没法直接 for 循环,那就上 while 循环吧
- 判断两个链表的相同节点,即面临着两重遍历,如果嵌套 while 循环则时间复杂度会到 O(n2)
为了避免嵌套循环,我自然想到用一个额外的集合先将 B 链表的节点记录下来
解题代码:
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
Set<ListNode> bSet = new HashSet<>();
ListNode temp = headB;
while (temp != null) {
bSet.add(temp);
temp = temp.next;
}
ListNode current = headA;
while (current != null) {
if (bSet.contains(current)) {
return current;
}
current = current.next;
}
return null;
}
}
运行结果:
复杂度分析:
时间复杂度:O(n+m)
- 空间复杂度:O(n)
引发的思考:
对于算法题,我还是习惯用 TDD 的方式来做,这样我可以参考题目中给的例子来构建测试用例,方便验证功能,也方便 DEBUG
对于此题的解法没有达到题目中的进阶要求,空间复杂度还是高了些,上面的代码也是我第一时间能想到的解法,其实一开始用的是 ArrayList,发现耗时在 900+ ms,才意识到 ArrayList 的 contains 方法的时间复杂度是 O(n),转而换成了 HashSet, 耗时立马降到了 5 ms,不过还不是最优解
后续也看了题解中高手的答案,不得不说确实厉害,自己还需要继续努力啊~