【单链表练习】 - 相交链表

题目描述

描述
编写一个程序,找到两个单链表相交的起始结点。
在这里插入图片描述
在结点c1开始相交(单链表不存在交叉,但存在相交)
当相交时,返回结点所在的值,不相交时返回null。在返回结果后,两个链表仍须保持原有的结构
可假定整个链表结构中没有循环。程序尽量满足O(n)时间复杂度,且仅用O(1)内存。


解题分析:

思路1:
用A链表的每一个结点的地址和B链表中的所有节点的地址比较,如果存在地址相同,则相交。并返回第一个相交的结点。
时间复杂度为O(M*N)

思路2:尾节点相同就是相交,否则就不相交,并求相交结点。
判断相交:分别遍历两个链表,判断最后一个结点的地址是否相同。
求相交结点:如果两个链表长度不同,则先让长的链表走长度差L1-L2步,再两个链表同时走。当两个结点相同时,结束并返回相交的结点。

代码实现2:

struct ListNode
{
    
    
	int val;
	struct ListNode* next;
};
struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB)
{
    
    
	if (headA == NULL || headB == NULL)
	{
    
    
		return NULL;
	}
    //1、判断是否相交
    //定义两个变量存放头结点来操作,防止迭代时头结点的值改变
    struct ListNode* tailA = headA;
    struct ListNode* tailB = headB;
    //2、计算两个链表的长度
    int lenA = 1;//这是从1开始
    int lenB = 1;
    while (tailA->next != NULL)
	{
    
    
		lenA++;
		tailA = tailA->next;
	}
	while (tailB->next != NULL)
	{
    
    
		lenB++;
		tailB = tailB->next;
	}
	if(tailA != tailB)
    {
    
    
        return NULL;
    }
    //3、计算两链表长度的差值
	int subValue = abs(lenA - lenB);//三目运算符也可以
	//4、判断两个链表的长度关系:分三种情况,lenA>lenB,lenA<lenB,lenA=lenB
	//假设默认lenA>lenB
	struct ListNode* longList = headA;//这里还要用到头指针,所以前面不用头指针迭代。
	struct ListNode* shortList = headB;
	//矫正
	if (lenB > lenA)
	{
    
    
		longList = headB;
		shortList = headA;
	}
	//5、长的链表的指针先走subValue步
	while (subValue)//subValue--,走subValue步
	{
    
    
		longList = longList->next;
		subValue--;
	}
	//注意:遍历下标,一般用for循环。
	
	//6、两个指针同时走
	while (longList != shortList)
	{
    
    
		longList = longList->next;
		shortList = shortList->next;
	}
    return longList;//返回任意一个指针即可
}

思路3:求交点:长的链表先走(长度差)步,在同时走,第一个地址相同的就是交点。
计算A和B两个链表的长度,假设分别为lA、lB(A比B短),差值为k,
两个指针headA、headB,分别指向两个链表的头,让他们同时走,headA(短)每次走一步,headB(长)每次走k步或者让headB(长)先走k步,再同时走(方法2)。
当他们的地址相同时,即为交点的结点的地址。
注意: 前面是先判断尾节点是否相同,判断是否相交。再求相交节点。 下面是假设相交,求相交节点的,如果存在相交节点,则判断相交。

代码实现3:

struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB)
{
    
    
	//1、计算两个链表的长度
	//定义两个变量存放头结点,防止迭代时头结点的值改变
	struct ListNode* curA = headA;
	int lA = 0;
	while (curA != NULL)
	{
    
    
		lA++;
		curA = curA->next;
	}
	struct ListNode* curB = headB;
	int lB = 0;
	while (curB != NULL)
	{
    
    
		lB++;
		curB = curB->next;
	}
	//2、判断两个链表的长度关系:分三种情况,lA>lB,lA<lB,lA=lB
	//假设默认lA>lB
	struct ListNode* longList = headA;
	struct ListNode* shortList = headB;
	if (lB > lA)
	{
    
    
		longList = headB;
		shortList = headA;
	}
	//3、计算两链表长度的差值
	int subValue = abs(lA - lB);
	//4、长的链表的指针先走subValue步
	while (subValue)
	{
    
    
		longList = longList->next;
		subValue--;
	}
	//5、两个指针同时走
	while (longList)//有一个链表走到尾
	{
    
    
		if (longList == shortList)
		{
    
    
			return longList;
		}
		longList = longList->next;
		shortList = shortList->next;
	}

	//来到这里,说明走到尾了也没有找到相交
	return NULL;
}

猜你喜欢

转载自blog.csdn.net/qq_48163964/article/details/130011719