题目描述
输入两个链表,找出它们的第一个公共结点。
两个链表如果有公共节点,那么从两链表的某两个节点指向同一个节点。
时间复杂度O(mn)方法
从头节点开始,比较链表1每个节点指针是否和链表2的每个节点指针相等。
时间复杂度?空间复杂度O(n)
将链表1每个节点的指针放入set中,遍历链表2,看节点是否已经在set中,如果在,说明该节点就是公共节点。
#include<set>
#include<iterator>
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1 == NULL ||pHead2 == NULL) return NULL;
set<ListNode*> myset;
set<ListNode*>::iterator iter;
ListNode* node = pHead1;
while(node != NULL)
{
myset.insert(node);
node = node->next;
}
node = pHead2;
while(node != NULL)
{
iter = myset.find(node);
if(iter != myset.end())
return node;
node = node->next;
}
return NULL;
}
};
上面的做法好像不太对。。。
从后面节点往前依次比较两链表的节点是否相等,链表为单链表,先读取前面的节点,要先操作后面的节点即先进后出,就要借助栈。将链表节点分别压入两个栈,比较每次的栈顶是否相等,若相等,分别弹出比较下一个栈顶,最后一次相等对应的节点即为第一个公共节点。
时间复杂度O(m+n),空间复杂度O(m+n)
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1 == NULL ||pHead2 == NULL) return NULL;
stack<ListNode*> stack1, stack2;
ListNode* node = pHead1, *pre = NULL;
while(node != NULL)
{
stack1.push(node);
node = node->next;
}
node = pHead2;
while(node != NULL)
{
stack2.push(node);
node = node->next;
}
//if(stack1.top() != stack2.top())
//return NULL;
while(!stack1.empty() && !stack2.empty())
{
if(stack1.top() == stack2.top())
{
pre = stack1.top();
stack1.pop();
stack2.pop();
}
else
{
return pre;
}
}
return pre;
}
};
要借助辅助栈的原因是两个链表的长度可能不相等,不能同时到达尾节点。改进方法是先分别遍历两个链表,得到其节点数,以及节点数的差,让长的链表先走节点数差的步数,两个链表再一起走,判断两链表经过的节点是否相等。第一次相等的节点即为第一个公共节点。无需辅助空间。
时间复杂度O(m+n),空间复杂度O(1)
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1 == NULL ||pHead2 == NULL) return NULL;
ListNode* node1 = pHead1, *node2 = pHead2;
int count1 = 0, count2 = 0;
while(node1 != NULL)
{
count1++;
node1 = node1->next;
}
while(node2 != NULL)
{
count2++;
node2 = node2->next;
}
node1 = pHead1;
node2 = pHead2;
int count = 0;
if(count1 > count2)
{
while(count < count1 - count2)
{
node1 = node1->next;
count++;
}
}
else if(count1 < count2)
{
while(count < count2 - count1)
{
node2 = node2->next;
count++;
}
}
while(node1 && node2)
{
if(node1 == node2)
return node1;
node1 = node1->next;
node2 = node2->next;
}
return NULL;
}
};