(剑指Offer)面试题37:两个链表的第一个公共结点

题目:

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

链表结点的定义如下:

struct ListNode{
    int val;
    ListNode* next;
    ListNode(int x):val(x),next(NULL){};
};

思路:

1、暴力法

遍历第一个链表,每遍历到一个结点,在第二个链表中顺序遍历,如果在第二个链表上有一个结点和该结点一样,说明两个链表在这个结点上重合,也就是第一个公共结点。

时间复杂度:O(mn)

2、堆栈法

如果两个链表存在公共结点,那么从第一个公共结点到链尾,所有结点都是重合的,如果我们从两个链表的尾部开始往前比较,最后一个相同的结点就是第一个公共结点。

但单链表只有后继指针,不能往回移动,我们可以很快想到了栈,将两个链表的结点分别放入两个栈里,这样两个尾指针都在栈顶,接着下就比较栈顶指针是否相同,如果是,则把栈顶弹出,继续比较下一个栈顶,直至找到最后一个相同的结点。

时间复杂度:O(m+n),空间复杂度:O(m+n)

3、两个指针

首先分别遍历两个链表A,B,得到各自的长度如lenA,lenB,假设lenA>lenB,然后让A指针先走lenA-lenB步,接着两个指针一块走,直至相遇即找到第一个公共结点。

时间复杂度:O(m+n)

代码:

这里只实现方法3

struct ListNode{
    int val;
    ListNode* next;
    ListNode(int x):val(x),next(NULL){};
};

unsigned int GetListLength(ListNode* pHead){
    unsigned int len=0;
    while(pHead!=NULL){
        len++;
        pHead=pHead->next;
    }
    return len;
}

ListNode* FindFirstCommonNode(ListNode* pHead1,ListNode* pHead2){
    unsigned int len1=GetListLength(pHead1);
    unsigned int len2=GetListLength(pHead2);
    ListNode* pLong=pHead1;
    ListNode* pShort=pHead2;
    unsigned lenDiff=len1-len2;
    if(len1<len2){
        pLong=pHead2;
        pShort=pHead1;
        lenDiff=len2-len1;
    }

    for(unsigned int i=0;i<lenDiff;i++)
        pLong=pLong->next;

    while(pShort!=NULL && pLong!=NULL && pShort!=pLong){
        pShort=pShort->next;
        pLong=pLong->next;
    }

    ListNode* pFirstCommonNode=pLong;

    return pFirstCommonNode;
}

在线测试OJ:

http://www.nowcoder.com/books/coding-interviews/6ab1d9a29e88450685099d45c9e31e46?rp=2

AC代码:

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) {
        int len1=GetListLength(pHead1);
        int len2=GetListLength(pHead2);
        ListNode* pLong=pHead1;
        ListNode* pShort=pHead2;
        int lenDiff=len1-len2;
        if(len1<len2){
            pLong=pHead2;
            pShort=pHead1;
            lenDiff=len2-len1;
        }
        
        for(int i=0;i<lenDiff;i++)
            pLong=pLong->next;
        
        while(pLong!=NULL && pShort!=NULL && pLong!=pShort){
            pLong=pLong->next;
            pShort=pShort->next;
        }
        
        ListNode* pFirstCommonNode=pLong;
        return pFirstCommonNode;
    }
    
    unsigned int GetListLength(ListNode* pHead){
        unsigned int len=0;
        while(pHead!=NULL){
            ++len;
            pHead=pHead->next;
        }
        return len;
    }
};

  

 

posted @ 2015-07-26 15:37  AndyJee  阅读(605)  评论(0编辑  收藏  举报