剑指offer——两个链表的第一个公共结点

题目描述

输入两个链表,找出它们的第一个公共结点。

两个链表如果有公共节点,那么从两链表的某两个节点指向同一个节点。

时间复杂度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;
    }
};

猜你喜欢

转载自blog.csdn.net/Eartha1995/article/details/81174747