题目:
朴素双指针法:
//典型双指针问题,先根据两个链表的长度把两个指针所指位置平齐,然后再同时双指针扫描,一旦相等则为交点。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int L1 = getLen(headA);
int L2 = getLen(headB);
//双指针平齐
if(L1>L2){
int gap = L1-L2;
for(int i=1;i<=gap;i++)
headA = headA->next;
}
else{
int gap = L2-L1;
for(int i = 1;i<=gap;i++)
headB = headB->next;
}
//双指针移动:
while(headA!=headB){
headA = headA->next;
headB = headB->next;
}
return headB;
}
private:
int getLen(ListNode* head){
if(head)
return getLen(head->next)+1;
else
return 0;
}
};
效率尚可
成环法(时间复杂度高,但实用性强):
代码
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(!headA||!headB)
return nullptr;
ListNode* t1 = headA;
ListNode* t2 = headB;
while(t1!=t2){
//如果t1或t2到null了就直接等于头指针(相当于循环)
//这里判断t1和t2而不是t->next是因为需要经过null状态。
//要是跳过了null状态,如果两者没有相交则无限循环。
t1 = t1?t1->next:headA;
t2 = t2?t2->next:headB;
}
return t1;
}
};
原理解析:
这里图解是跳过了null状态,但是实际不能跳过,加入null状态,也就是在最后多加一个结点即可。
没错时间复杂度确实是O(n^2)(别看代码简短)
进阶双指针法(利用同时遍历长度相等原理)
代码
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(!headA||!headB)
return nullptr;
ListNode* t1 = headA;
ListNode* t2 = headB;
while(t1!=t2){
//只需要在成环法的基础上改为遍历到另一个链表
t1 = t1?t1->next:headB;
t2 = t2?t2->next:headA;
}
return t1;
}
};
详解