数据结构&算法&人工智能

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

2020-04-21  本文已影响0人  零岁的我

题目描述
输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)

解题思路
典型的用空间换时间做法:
同时遍历两条链表,并将两条链表中访问过的结点存到同一个set容器中,因为set容器中不存在重复结点,当在set中能检索到当前访问结点时,说明该结点就是两条链表的公共结点,在遍历短链表的时候被存到set中了。

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
typedef ListNode* node;
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        set<node> st;
        node p=pHead1;
        node q=pHead2;
        while(p || q){
            if(p){
                if(st.find(p)==st.end()) st.insert(p),p=p->next;
                else return p;
            }
            if(q){
                if(st.find(q)==st.end()) st.insert(q),q=q->next;
                else return q;
            }
        }
        return NULL;
    }
};

思路2
同思路1差不多,这里也是先遍历两个链表,但是这里用map标记访问过的结点。

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
typedef ListNode* node;
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        map<node,bool> mp;
        node p=pHead1;
        node q=pHead2;
        while(p || q){
            if(p){
                if(mp[p]==true) return p;
                else mp[p]=true, p=p->next;
            }
            if(q){
                if(mp[q]==true) return q;
                else mp[q]=true, q=q->next;
            }
        }
        return NULL;
    }
};

思路3
不需要额外的辅助空间。考虑如下情况:
链表1:a->b->c->d->e->3->4->null
链表2:1->2->3->4->null
第一个公共结点:3
公共尾部:3->4->null
初始化两个指针p、q分别指向链表1和链表2的头部,当两个指针遍历到各自链表的尾部时,改变指针指向,使其指向另一条链表的头部,继续遍历,最终两个指针遍历结点的顺序如下:
指针p:a->b->c->d->e->3->4->null->1->2->3->4->null
指针q:1->2->3->4->null->a->b->c->d->e->3->4->null
很明显,如果链表1和链表2有公共结点,那么两个指针肯定会相遇,如果没有公共结点,则两个指针最后都指向null结点,还是相遇了。
时间复杂度:O(n+m)

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
typedef ListNode* node;
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        node p=pHead1;
        node q=pHead2;
        while(p != q){
            p= (p==NULL? pHead2:p->next); //修改指针p指向重新指向另一条链表
            q= (q==NULL? pHead1:q->next);//修改指针q指向重新指向另一条链表
        }
        return p;
    }
};
上一篇 下一篇

猜你喜欢

热点阅读