编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:
在节点 c1 开始相交。
示例 1:
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Reference of the node with value = 8
输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
示例 2:
输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Reference of the node with value = 2
输入解释:相交节点的值为 2 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。在
示例 3:
解题思路:
如果两者长度不同先找出他们的长度,然后算出长度差,在让长的先移动长度差相等的步数,再利用两个指针一起移动,如果两个指针相等则说明,已经到了同样的数字
代码如下:
```cpp
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(headA==NULL ||headB==NULL){
return NULL;
}
auto a=headA;
auto b=headB;
int lengthA=0,lengthB=0;
while(a!=NULL){
a=a->next;
lengthA++;
}
while(b!=NULL){
b=b->next;
lengthB++;
}
auto q=headA;
auto p=headB;
if(lengthA>=lengthB){
int j=0;
while(j<lengthA-lengthB){
q=q->next;
j++;
}
while(q!=NULL &&p!=NULL){
if(q==p){
return q;
}
q=q->next;
p=p->next;
}
}
else{
int i=0;
while(i<lengthB-lengthA){
p=p->next;
i++;
}
while(q!=NULL &&p!=NULL){
if(q==p){
return p;
}
q=q->next;
p=p->next;
}
}
return NULL;
}
};
```
以上方法耗时较长,因此进行改良添加函数length()来计算长度
代码如下:
```cpp
class Solution {
public:
int length(ListNode *head){//计算长度的函数
int i=0;
auto a=head;
while(a!=NULL){
a=a->next;
i++;
}
return i;
}
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(headA==NULL ||headB==NULL){
return NULL;
}
int lengthA,lengthB;
lengthA=length(headA);
lengthB=length(headB);
auto q=headA;
auto p=headB;
if(lengthA>=lengthB){//A比B长
int j=0;
while(j<lengthA-lengthB){//A先进行移动
q=q->next;
j++;
}
while(q!=NULL &&p!=NULL){//两者开始一起移动
if(q==p){//q已经等于b
return q;
}
q=q->next;
p=p->next;
}
}
else{
int i=0;
while(i<lengthB-lengthA){
p=p->next;
i++;
}
while(q!=NULL &&p!=NULL){
if(q==p){
return p;
}
q=q->next;
p=p->next;
}
}
return NULL;
}
};
```