Una serie de problemas dejó fortuna título class3- base ley 14 intersecta dos lista única

1. Tema

[Título] En este problema, no puede ser un anillo de una sola cadena, puede acíclica. Dados dos sola head1 lista y head2 El nodo de cabeza, la intersección de las dos listas puede o no se intersecan. Por favor implementar una función, si la intersección de las dos listas, una vuelta al primer nodo de intersección, y si no se cruzan, se puede devolver null. Requisitos: 1 si la longitud de la lista es N, la longitud de la cadena 2 es H, para conseguir el tiempo complejidad solicitado O (N + M), para lograr el espacio complejidad O adicional solicitada (1).

2. Análisis

La idea general es determinar primero las dos listas no tienen anillo, si las dos listas no anillo (el nodo de anillo está vacío) y luego la solución de intersección cadena acíclica; si hay anillos (nodo de entrada no está vacío) entonces allí se cruzan la solución de anillo de la cadena. Un anillo tiene un cierto acíclico disjuntos.

(1) determinar si el anillo: hay nodo de ingreso de un bucle de vuelta, retorno acíclico vacía

Pensando 1: usar una tabla hash para saber si la tecla de entrada el mapa; la cabeza para atravesar a través de la siguiente, si no, entonces añadido al mapa, si está presente, de retorno al lado de la última en blanco indica que no hay anillos. (Realización concreta continuación)
Ideas 2: No utilice una tabla hash, lista para acelerar dos punteros, el puntero se mueve rápidamente dos veces, una vez para ir a un puntero paso lento. No necesariamente puntero rápido fue el anillo en blanco, si la hay, entonces la velocidad del puntero del anillo debe cumplir con manos rápidas, y empezar de nuevo, un paso, el puntero se reúnen cierta velocidad en el punto de entrada.

//判断有无环,思路二实现
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) encontrar el acíclico nodo de intersección

Para dos listas, (1) En los análisis se nula es acíclico, el condición de bucle no, encontrar la siguiente nodo de intersección.
1 idea: el uso del mapa, la cadena 1 en el mapa, recorrer la lista 2, encontrar un nodo es el primer nodo de intersección (realización concreta continuación)
Ideas 2: no utilizar un mapa, atravesando respectivamente las Estadísticas lista 1 y lista 2 la longitud de la longitud, el fin último nodo. Analizando END1 y dirección de memoria end2 no es lo mismo, si no puede no idénticos se cruzan. Si el mismo no es necesariamente el primer nodo de intersección, reiterar, siempre ir | length1 - longitud2 |, a continuación, recorrer las dos cadenas juntas, misma dirección del primer nodo es el nodo de intersección.

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) Determinar el nodo de intersección cuando el anillo

Se refiere a un anillo de cicloalquilo tiene dos listas, para una única lista enlazada tiene un anillo de una cadena acíclica de intersección caso imposible .
Un cicloalquilo entonces la lista se pueden agrupar en tres categorías se cruzan, ① dos cadenas no se cruzan, ② intersección Además, el primer anillo, ③ de intersección en el anillo.
Por debajo de estos tres casos, puede haber soluciones utilizando los enlaces de punto (1) devueltos. loop1 == loop2Cuando el nodo de entrada es el mismo que el caso de dos anillos ②, esta vez parte de anillo golpes, pero sólo en una parte equivalente a la intersección de la cadena problema acíclico que la descrita anteriormente (2). El otro caso es diferentes puntos de ingreso, el uso bucle1 en el recorrido del anillo, que atraviesan el anillo en la parte trasera círculo bucle1 bucle1 a la hora aún no ha encontrado la explicación LOOP2 dos anillos no se cruzan, es el caso ①; pero se encontró durante el recorrido LOOP2 es el caso ③, puede ser devuelto bucle1 o LOOP2.

Aquí Insertar imagen Descripción

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;
	}
}
Publicado 51 artículos originales · ganado elogios 1 · vistas 1377

Supongo que te gusta

Origin blog.csdn.net/shi_xiao_xuan/article/details/103816431
Recomendado
Clasificación