leetcode 面试题52:两个链表的第一个公共节点

题目链接:https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof/ 

题目分析

1.公共节点:两个链表拥有公共节点不是指两个链表的节点的数据域相同,而是指两个链表的指针指向同一个节点,即具有相同的地址。

2.需要注意的是:由于单链表只有一个next域,所以只要找到两个链表的第一个公共节点,那么从第一个公共节点开始,两个链表后面的节点均是重合的,即两个有公共节点而部分重合的单链表,拓扑形状看起来像Y,而不是X。

3.解决方法:

    a.暴力法:对于第一个链表的每个节点,遍历第二个链表的每个节点,知道找到第一个公共节点为止。时间复杂度为O(len1+len2),其中len1、len2分别是第一个链表和第二个链表的长度。

    b.可以将长的链表分成三部分:

                                                    part1:比短得链表多的部分;

                                                    part2:长的链表和短的链表重合但是不是公共节点的部分;

                                                    part3:两个链表的公共部分;

     用公式表达:M1 + M2 + M3 = M2' + M3;

     基本的思路:假设len1  > len2,即第一个链表长度大于第二个链表

                           遍历(len1-len2)部分,即 part1部分,然后遍历第一个链表和第二个链表的公共部分,找第一个共有节                点。

                          其他情况类似。


 

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode *longlist,*shortlist;
	int len1 = length(headA);
	int len2 = length(headB);
	int dist;
	if(len1 > len2)
	{
		longlist = headA;
		shortlist = headB;
		dist = len1 - len2;
	}
	else
	{
		longlist = headB;
		shortlist = headA;
		dist = len2 - len1;
	}
	while(dist--)
		longlist = longlist->next;
	while(longlist != NULL)
	{
		if(longlist == shortlist)
			return longlist;
		else
			{
				longlist = longlist->next;
				shortlist = shortlist->next;
			}
	}
	return NULL;
}
int length(struct ListNode *List)
{
	//求链表长度
	struct ListNode *p = List;
	int len = 0;
	while(p != NULL)
	{
		len++;
		p = p->next;
	}
	return len;
}

上述代码:用时30%,内存100%。

你可能感兴趣的:(数据结构和算法,链表,单链表)