[Single linked list exercise] - Intersecting linked list

topic description

Description
Write a program to find the starting node where two singly linked lists intersect.
insert image description here
Start to intersect at node c1 (single-linked list does not have intersection, but there is intersection)
. When intersecting, return the value where the node is located, and return null when disjoint. After returning the result, the two linked lists must still maintain the original structure.
It can be assumed that there is no cycle in the entire linked list structure. The program tries to meet O(n) time complexity and only uses O(1) memory.


Problem solving analysis:

Idea 1:
Use the address of each node in the A linked list to compare with the addresses of all nodes in the B linked list. If there are the same addresses, they will intersect. And returns the first intersecting node.
The time complexity is O(M*N)

Idea 2: If the tail nodes are the same, they intersect, otherwise they will not intersect, and find the intersecting node.
Judgment intersection: Traverse the two linked lists separately, and judge whether the address of the last node is the same.
Find the intersection node: If the lengths of the two linked lists are different, first let the long linked list walk the length difference L1-L2 steps, and then walk the two linked lists at the same time. When the two nodes are the same, end and return the intersected node.

Code implementation 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;//返回任意一个指针即可
}

Idea 3: Find the intersection point: the long linked list goes first (length difference) step, and at the same time, the first address with the same address is the intersection point.
Calculate the length of the two linked lists A and B, assuming they are lA and lB (A is shorter than B), the difference is k, the
two pointers headA and headB point to the heads of the two linked lists respectively, let them go at the same time, headA ( Short) take one step each time, headB (long) takes k steps each time or let headB (long) take k steps first, and then walk at the same time (method 2).
When their addresses are the same, it is the address of the node of the intersection.
注意: 前面是先判断尾节点是否相同,判断是否相交。再求相交节点。 下面是假设相交,求相交节点的,如果存在相交节点,则判断相交。

Code implementation 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;
}

Guess you like

Origin blog.csdn.net/qq_48163964/article/details/130011719