剑指offer P253解题思路1:两个链表全部入栈,然后对比栈顶结点,如果相同,同时弹出,直到找到最后一个相同结点。
辅助栈实现:时间复杂度和空间复杂度都是O(m+n)
书中解题思路2:算出两个链表的长度length1,length2, k = abs(lenght2-lenght1)
先让长的链表走K步,然后再同步走,第一个相同的结点就是公共结点。
时间复杂度:O(m+N),空间复杂度O(1)
思路3:用双指针,遍历这两个链表,用一个游标i去遍历list1, j 去遍历list2,
i到达list1终点后继续去遍历list2, j到达list2的终点后继续去遍历list1, 第二次遍历两个游标肯定在第一个公共结点相遇。时间复杂度:O(m+n),空间复杂度O(1)
1.栈实现
/*
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 || !pHead2) return nullptr;
//辅助栈实现
stack<ListNode*> stack1;
stack<ListNode *>stack2;
ListNode *pCur = pHead1;
while(pCur){
stack1.push(pCur);
pCur = pCur->next;
}
pCur = pHead2;
while(pCur){
stack2.push(pCur);
pCur = pCur->next;
}
pCur = nullptr;
while(!stack1.empty() && !stack2.empty()){
if(stack1.top() == stack2.top())pCur = stack1.top();
else break;
stack1.pop();
stack2.pop();
}
// if(stack1.empty() && stack2.empty())pCur = pHead1;
return pCur;
}
};
2.长的链表先走k步
/*
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 || !pHead2) return nullptr;
//长链表先走k步
int length1 = 0;
ListNode *pCur = pHead1;
while(pCur){
++length1;
pCur = pCur->next;
}
int length2 = 0;
pCur = pHead2;
while(pCur){
++length2;
pCur = pCur->next;
}
pCur = pHead1;
ListNode *pCur2 = pHead2;
int k = abs(length1 - length2);
if(length1 >= length2){
while(k--){
pCur = pCur->next;
}
}else{
while(k--)pCur2 = pCur2->next;
}
while(pCur && pCur2 && pCur != pCur2){
pCur2 = pCur2->next;
pCur = pCur->next;
}
return pCur;
}
};
解题3:游标走完一个链表然后去走第二个链表,只走一次,需要设置标志位
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
//双指针法,
if(!pHead1 || !pHead2) return nullptr;
ListNode *pCur1 = pHead1;
ListNode *pCur2 = pHead2;
int flag1= 0;
int flag2 = 0;//标志位设置只走两轮
while(pCur2 != pCur1){
pCur1 = pCur1->next;
pCur2 = pCur2->next;
if(pCur1 == nullptr && flag1 ==0 )
{
flag1 = 1;
pCur1 = pHead2;
}
if(pCur2 == nullptr && flag2 ==0)
{
flag2 = 1;
pCur2 = pHead1;
}
}
return pCur1;
//栈实现
// stack<ListNode*> stack1;
// stack<ListNode *>stack2;
// ListNode *pCur = pHead1;
// while(pCur){
// stack1.push(pCur);
// pCur = pCur->next;
// }
// pCur = pHead2;
// while(pCur){
// stack2.push(pCur);
// pCur = pCur->next;
// }
// pCur = nullptr;
// while(!stack1.empty() && !stack2.empty()){
// if(stack1.top() == stack2.top())pCur = stack1.top();
// else break;
// stack1.pop();
// stack2.pop();
// }
// if(stack1.empty() && stack2.empty())pCur = pHead1;
// return pCur;
//长链表先走k步
// int length1 = 0;
// ListNode *pCur = pHead1;
// while(pCur){
// ++length1;
// pCur = pCur->next;
// }
// int length2 = 0;
// pCur = pHead2;
// while(pCur){
// ++length2;
// pCur = pCur->next;
// }
// pCur = pHead1;
// ListNode *pCur2 = pHead2;
// int k = abs(length1 - length2);
// if(length1 >= length2){
// while(k--){
// pCur = pCur->next;
// }
// }else{
// while(k--)pCur2 = pCur2->next;
// }
// while(pCur && pCur2 && pCur != pCur2){
// pCur2 = pCur2->next;
// pCur = pCur->next;
// }
// return pCur;
}
};