A series of problems left Fortune law basis class3- title 14 intersects two single list

1. Topic

[Title] In this problem, there may be a single chain ring, may acyclic. Given two single list head1 and head2 The head node, the intersection of the two lists may or may not intersect. Please implement a function, if the intersection of two lists, a return to the first intersection node; if not intersect, you can return null. Requirements: 1 if the length of the list is N, the length of the chain 2 is M, to achieve the requested time complexity O (N + M), to achieve the requested additional space complexity O (1).

2. Analysis

The general idea is to first determine the two lists have no ring, if the two lists do not ring (the ring node is empty) and then solving acyclic chain intersect; if there are rings (ingress node is not empty) then there intersect solving ring chain. A ring has a certain disjoint acyclic.

(1) determine whether the ring: there is ingress node loops back, acyclic return empty

Thinking 1: use a hash table to find whether the enter key the map; head to traverse through the next, if not then added to the map, if present, return directly next to the last blank indicates no rings. (Concrete realization Continued)
ideas 2: Do not use a hash table, ready to speed two pointers, pointer fast moving twice, once to go a step slow pointer. Not necessarily fast pointer went empty ring, if there is, then the speed of the ring pointer must meet, quick hands and start over again, a step, meet certain speed pointer at the ingress point.

//判断有无环,思路二实现
List getLoopNode(List head)
{
	head = head->next;//从第一个节点开始
	//因为快指针需要走两步,两步内为空的必然无环
	if (head == NULL || head->next == NULL || 
		head->next->next == NULL)
			return NULL;
	//定义快慢指针
	List fast = head->next->next;
	List slow = head->next;
	
	while(fast != slow)
	{
		//快指针为空时直接返回不相遇
		if (fast == NULL || fast->next == NULL) 
			return NULL;
		//快指针一次走两步,慢指针一次走一步
		fast = fast->next->next;
		slow = slow->next;
	}
	//快指针返回开始位置
	fast = head;
	//第二次快指针一次走一步
	while(fast != slow)
	{
		fast = fast->next;
		slow = slow->next;
	}
	return fast;
}

(2) find the intersection node acyclic

For two lists, (1) in analysis are null is acyclic, the loop condition no, find the next intersection node.
1 idea: use map, the chain 1 into the map, traverse the list 2, find a node is the first intersection node (concrete realization Continued)
ideas 2: do not use map, respectively traversing the list 1 and list 2 Statistics the length of the length, the last node end. Analyzing end1 and end2 memory address is not the same, if not identical can not intersect. If the same is not necessarily the first intersection node, re-iterate, so long go | length1 - length2 |, then traverse the two chains together, same address of the first node is the intersection node.

List noLoop(List head1,List head2)
{
	head1 = head1->next;
	head2 = head2->next;
	List cur1 = head1;
	List cur2 = head2;
	//计算length,存储最后一个节点
	int len1 = 0;
	int len2 = 0;
	List end1 = cur1;
	List end2 = cur2;
	while(cur1 != NULL)
	{
		end1 = cur1;
		len1++;
		cur1= cur1->next;
	}
	while(cur2 != NULL)
	{
		end2 = cur2;
		len2++;
		cur2= cur2->next ;
	}
	//找交点
	
	if(end1 != end2)//end1、end2是指针所指的地址相等
		return NULL;
	int dist = abs(len1 - len2);
	int count = 0;
	cur1 = len1 > len2 ? head1 : head2;//cur1是长链
	cur2 = len1 > len2 ? head2 : head1;//cur2是短链
	//先走多余的步数
	while(count < dist)
	{
		cur1 = cur1->next;
		count++;
	}
	while(cur1 != cur2)
	{
		cur1 = cur1->next;
		cur2 = cur2->next;
	}
	return cur1;//return cur2也可以
}

(3) Determine the intersection node when ring

Refers to a cycloalkyl ring has two lists, for a single linked list has a ring of a chain acyclic intersecting case impossible .
A cycloalkyl then the list can be grouped into three categories intersect, ① two chains do not intersect, ② Further intersecting the first ring, ③ intersect on the ring.
Below these three cases, there may be solutions using point links (1) returned. loop1 == loop2When the ingress node is the same as the case of two rings ②, this time blows ring portion, but only on a portion equivalent to the intersection of chain acyclic problem that the above-described (2). The other case is different ingress points, use loop1 in the ring traversal, traversing the ring in loop1 loop1 circle back to the time still did not find the explanation loop2 two rings do not intersect, is the case ①; but found during traversal loop2 is the case ③, can be returned loop1 or loop2.

Here Insert Picture Description

List bothLoop(List head1,List loop1, List head2,List loop2)
{
	head1 = head1->next;
	head2 = head2->next;
	//入环节点相同,等同于无环相交
	if(loop1 == loop2)
	{
		List cur1 = head1;
		List cur2 = head2;
		//计算length,存储最后一个节点
		int len1 = 0;
		int len2 = 0;
		//只讨论入环节点之前的部分
		while(cur1 != loop1)
		{
			len1++;
			cur1= cur1->next;
		}
		while(cur2 != loop2)
		{
			len2++;
			cur2= cur2->next ;
		}
		int dist = abs(len1 - len2);
		int count = 0;
		cur1 = len1 > len2 ? head1 : head2;
		cur2 = len1 > len2 ? head2 : head1;
		//先走多余的步数
		while(count < dist)
		{
			cur1 = cur1->next;
			count++;
		}
		while(cur1 != cur2)
		{
			cur1 = cur1->next;
			cur2 = cur2->next;
		}
		return cur1;
	}
	//入环节点不同
	else
	{
		List cur1 = loop1->next;
		while(loop1 != cur1)//只判断环之前的部分
		{
			if(cur1 == loop2)
			{
				return loop1;
			}
			cur1  = cur1 ->next ;
		}
		return NULL;
	}
}
Published 51 original articles · won praise 1 · views 1377

Guess you like

Origin blog.csdn.net/shi_xiao_xuan/article/details/103816431