
进阶: 你能否设计一个时间复杂度 O(m + n) 、仅用 O(1) 内存的解决方案?
法(1)√
如果不考虑金庸O(1)内存的话,就是用HashSet去做。先遍历链表A把每个节点用HashSet存起来,然后遍历链表B,用HashSet的contains方法
时间复杂度:O(m+n)
空间复杂度:O(n)
法(2)×
遍历一遍B,数出来链表B的个数。
遍历一遍A,一边遍历一边把A的链条全拆了.
再遍历一遍B,看看数出来的个数跟一开始是否一样,一样的话就无相交,不一样的话返回B的最后一个节点。
但是看了一眼题目,不让动链表结构。
时间复杂度:O(m+n+n)
空间复杂度:O(1)
法(3)×
观察到节点里的int val取值是
1 <= Node.val <= 105
那可以采用标记的方法。
遍历一遍A,把A的val都变成负数,然后再遍历B,遇到的第一个负数就是要返回的结果。但是题目,不让动链表结构,也包括每个节点里存的val值。
时间复杂度:O(m+n)
空间复杂度:O(1)
法(4)进阶
关键在于"让A和B距离相交节点相同的距离处开始一起走 ",这样就可以在相同节点相遇了。处理办法是假如A比B要长step,那就让A先走step步,然后A和B开始一起走。
java
/**
* 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) {
//计算A的长度
int lengthA=0;
ListNode indexA=headA;
while(indexA!=null){
lengthA++;
indexA=indexA.next;
}
//计算B的长度
int lengthB=0;
ListNode indexB=headB;
while(indexB!=null){
lengthB++;
indexB=indexB.next;
}
indexA = headA;
indexB = headB;
//假如A比B长,那A先走step步
if(lengthA>lengthB){
int step = lengthA-lengthB;
for(int i=1; i<=step; i++){
indexA = indexA.next;
}
//假如B比A长,那B先走step步
}else if(lengthA<lengthB){
int step = lengthB-lengthA;
for(int i=1; i<=step; i++){
indexB = indexB.next;
}
}
//一起走
while(indexA!=null){
if(indexA==indexB) return indexA;
indexA=indexA.next;
indexB=indexB.next;
}
return null;
}
}
时间复杂度:O(计算A的长度m+计算B的长度n+后来走的长度x)=O(m+n+x)
空间复杂度:O(1)
法(4.1)进阶
这里用到了数学。
跟法(4)不同的是,法(4)是让其中一个先走。这里没有谁先走,从一开始就一起走。
设共同的长度为c,链表A多出来的长度为a,链表B多出来的长度是b

A和B都从头结点开始一起走,一次一步,当A走到尾节点时(a+c),从B的头结点开始继续走,当B走到尾结点时(b+c),从A的头结点开始继续走,这样两人相遇的地方就是相交节点。
因为a+c+b 等于b+c+a啊!
时间复杂度:O(a+b+c)=O(m+b)或O(n+a)
空间复杂度:O(1)
但是时间复杂度并没有比我的法(4)强到哪里去!!!还是用我的法(4)吧