题目要我们求得两个链表的交叉点,如果没有就返回NULL。值得注意的是题目对于时间复杂度和空间复杂度是有要求的。用暴力的遍历时间复杂度会是O(n^2),就不符合题目要求了。
这里我解题的思路是,如果两个链表有交叉点,那么从后往前数,数到某一个链表结束那么就一定会遇到交叉点。所以我把较长的链表的前面部分去掉,让两个链表等长之后就比两个链表有没有相同的节点,第一个相同的节点就是交叉点。
这里还有一个小优化:在数两个链表的长度的时候,我们肯定要遍历一次两个链表,这时可以比较一下两个链表的尾节点是否一致,不一致就一定没有交叉点,这样可以提前返回NULL,节省一点时间。
AC代码:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *nodeA,*nodeB;
if(headA == NULL || headB == NULL)
return NULL;
nodeA = headA;
nodeB = headB;
int sizeA = 1;
while(nodeA->next != NULL){
nodeA = nodeA->next;
sizeA++;
}
int sizeB = 1;
while(nodeB->next != NULL){
nodeB = nodeB->next;
sizeB++;
}
if(nodeA != nodeB)
return NULL;
nodeA = headA;
nodeB = headB;
if(sizeA>sizeB){
for(int i = 0; i< sizeA-sizeB;i++){
nodeA = nodeA->next;
}
}else{
for(int i = 0; i< sizeB-sizeA;i++){
nodeB = nodeB->next;
}
}
while(nodeA->next!=NULL && nodeB->next!=NULL){
if(nodeA == nodeB)
return nodeA;
nodeA=nodeA->next;
nodeB=nodeB->next;
}
if(nodeA!=nodeB)
return NULL;
else
return nodeA;
}