链表题一定要想到快慢指针
三种方法:
1.用一个map记录第一条链表每个结点是否出现,遍历第二条时判断即可。
2.我称之为相亲相爱法,因为两条链表的长度不确定,所以让两个指针分别走1+2两条链表的长度就可以了,这样走的就是相等了。两个结点相等时退出循环(这样就算两个结点都指向空结点也不会死循环)。当1为空,就让1指向链表2的头,2为空,就让2指向链表1的头。
3.算出两条链表的长度len1和len2,假设len1>len2,就让链表1的指针先走len1-len2步,然后再一起走就行了
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1 == NULL || pHead2 == NULL){
return NULL;
}
//法一来个map记录出现过的结点,遍历第二条链表时判断是否出现过
/*O(N),O(N)
map<ListNode*,int> ma;
while(pHead1 != NULL){
ma[pHead1]++;
pHead1 = pHead1->next;
}
while(pHead2 != NULL){
if(ma[pHead2] != 0){
return pHead2;
}
pHead2 = pHead2->next;
}
return NULL;*/
//最好是O(1)的空间复杂度,链表就要想到快慢指针
//两种快慢指针的思路1:相亲相爱
/*ListNode* a = pHead1;
ListNode* b = pHead2;
while(a != b){
//如果两个指针同时到达NULL,就把NULL看做公共节点
//所以不能用a->next==null来判断,这样a和b永远不会变成NULL,如果没有交点就是死循环了
a = a == NULL ? pHead2 : a->next;
b = b == NULL ? pHead1 : b->next;
}
return a;*/
//2:长的先走
int len1 = 0, len2 = 0;
ListNode* a = pHead1;
ListNode* b = pHead2;
while(a != NULL){
len1++;
a = a->next;
}
while(b != NULL){
len2++;
b = b->next;
}
if(len1 > len2){
//第一条比较长,走len1-len2步
while((len1 - len2) != 0){
pHead1 = pHead1->next;
len1--;
}
}
else{
while((len2-len1)!=0){
pHead2 = pHead2->next;
len2--;
}
}
while(pHead1 != pHead2){
pHead1 = pHead1->next;
pHead2 = pHead2->next;
}
return pHead1;
}
};