Leetcode-23-Fusionar k listas enlazadas ascendentes

fusión secuencial

Debe estar familiarizado con la fusión de dos listas enlazadas ascendentes. Su algoritmo es el siguiente:

struct ListNode* MergeList(struct ListNode* head1, struct ListNode* head2)
{
    
    
	struct ListNode* cur1 = head1, * cur2 = head2;
	struct ListNode* newhead = NULL, * tail = NULL;
	while (cur1 && cur2)
	{
    
    
		if (cur1->val <= cur2->val)
		{
    
    
			if (newhead == NULL)
			{
    
    
				newhead = tail = cur1;
			}
			else
			{
    
    
				tail->next = cur1;
				tail = cur1;
			}
			cur1 = cur1->next;
		}
		else
		{
    
    
			if (newhead == NULL)
			{
    
    
				newhead = tail = cur2;
			}
			else
			{
    
    
				tail->next = cur2;
				tail = cur2;
			}
			cur2 = cur2->next;
		}
	}
	while (cur1)
	{
    
    
		if (newhead == NULL)
		{
    
    
			newhead = tail = cur1;
		}
		else
		{
    
    
			tail->next = cur1;
			tail = cur1;
		}
		cur1 = cur1->next;
	}
	while (cur2)
	{
    
    
		if (newhead == NULL)
		{
    
    
			newhead = tail = cur2;
		}
		else
		{
    
    
			tail->next = cur2;
			tail = cur2;
		}
		cur2 = cur2->next;
	}
	return newhead;
}

Dado que este tema es fusionar K listas enlazadas ascendentes, primero podemos fusionar las dos primeras listas enlazadas y luego fusionarnos con la tercera... y luego fusionarnos con la K-ésima.

inserte la descripción de la imagen aquí

Mira el código a continuación:

struct ListNode* MergeList(struct ListNode* head1, struct ListNode* head2)
{
    
    
	struct ListNode* cur1 = head1, * cur2 = head2;
	struct ListNode* newhead = NULL, * tail = NULL;
	while (cur1 && cur2)
	{
    
    
		if (cur1->val <= cur2->val)
		{
    
    
			if (newhead == NULL)
			{
    
    
				newhead = tail = cur1;
			}
			else
			{
    
    
				tail->next = cur1;
				tail = cur1;
			}
			cur1 = cur1->next;
		}
		else
		{
    
    
			if (newhead == NULL)
			{
    
    
				newhead = tail = cur2;
			}
			else
			{
    
    
				tail->next = cur2;
				tail = cur2;
			}
			cur2 = cur2->next;
		}
	}
	while (cur1)
	{
    
    
		if (newhead == NULL)
		{
    
    
			newhead = tail = cur1;
		}
		else
		{
    
    
			tail->next = cur1;
			tail = cur1;
		}
		cur1 = cur1->next;
	}
	while (cur2)
	{
    
    
		if (newhead == NULL)
		{
    
    
			newhead = tail = cur2;
		}
		else
		{
    
    
			tail->next = cur2;
			tail = cur2;
		}
		cur2 = cur2->next;
	}
	return newhead;
}

struct ListNode* mergeKLists(struct ListNode** lists, int listsSize)
{
    
    
	if (listsSize == 0)
	{
    
    
		return NULL;
	}
	struct ListNode* newhead = lists[0];
	for (int i = 1; i < listsSize; i++)
	{
    
    
		newhead = MergeList(newhead, lists[i]);
	}
	return newhead;
}

Divide y conquistaras

Como estamos familiarizados con la fusión de dos listas enlazadas ascendentes, esta idea es transformar el problema en la fusión de dos listas enlazadas ascendentes.
Primero, divida la matriz de listas en dos secciones de igual tamaño, combine todas las listas vinculadas en estas dos secciones en una lista vinculada y finalmente combine las dos listas vinculadas. (Hay una sensación de tipo de fusión...)

inserte la descripción de la imagen aquí

Mira el código a continuación:

struct ListNode* MergeList(struct ListNode* head1, struct ListNode* head2)
{
    
    
	struct ListNode* cur1 = head1, * cur2 = head2;
	struct ListNode* newhead = NULL, * tail = NULL;
	while (cur1 && cur2)
	{
    
    
		if (cur1->val <= cur2->val)
		{
    
    
			if (newhead == NULL)
			{
    
    
				newhead = tail = cur1;
			}
			else
			{
    
    
				tail->next = cur1;
				tail = cur1;
			}
			cur1 = cur1->next;
		}
		else
		{
    
    
			if (newhead == NULL)
			{
    
    
				newhead = tail = cur2;
			}
			else
			{
    
    
				tail->next = cur2;
				tail = cur2;
			}
			cur2 = cur2->next;
		}
	}
	while (cur1)
	{
    
    
		if (newhead == NULL)
		{
    
    
			newhead = tail = cur1;
		}
		else
		{
    
    
			tail->next = cur1;
			tail = cur1;
		}
		cur1 = cur1->next;
	}
	while (cur2)
	{
    
    
		if (newhead == NULL)
		{
    
    
			newhead = tail = cur2;
		}
		else
		{
    
    
			tail->next = cur2;
			tail = cur2;
		}
		cur2 = cur2->next;
	}
	return newhead;
}
struct ListNode* mergeKLists1(struct ListNode** lists, int begin, int end)
{
    
    
	if (begin >= end)
	{
    
    
		return NULL;
	}
	int mid = begin + (end - begin) / 2;
	struct ListNode* ret1 =  mergeKLists1(lists, begin, mid);
	struct ListNode* ret2 = mergeKLists1(lists, mid+1, end);
	return MergeList(ret1, ret2);
}
struct ListNode* mergeKLists(struct ListNode** lists, int listsSize)
{
    
    
	if (listsSize == 0)
	{
    
    
		return NULL;
	}
	return mergeKLists1(lists, 0, listsSize - 1);
}

Fusión de nodos de selección de bucle

Esta idea es consistente con la idea de fusionar dos listas enlazadas ascendentes, la diferencia es que cada vez se selecciona el nodo más pequeño de las listas enlazadas de tamaño de listas.
Mira el código a continuación:

struct ListNode* mergeKLists(struct ListNode** lists, int listsSize)
{
    
    
	if (listsSize == 0)
	{
    
    
		return NULL;
	}
	struct ListNode* newhead=NULL, * tail=NULL;
	int flag = 1;
	while (flag)
	{
    
    
		int min = 10001;
		int minlog = -1;
		flag = 0;
		for (int i = 0; i < listsSize; i++)
		{
    
    
			if (lists[i] == NULL)
			{
    
    
				continue;
			}
			if (lists[i]->val < min)
			{
    
    
				flag = 1;
				min = lists[i]->val;
				minlog = i;
			}
		}
		if (flag)
		{
    
    
			if (newhead == NULL)
			{
    
    
				newhead = tail = lists[minlog];
				lists[minlog] = lists[minlog]->next;
			}
			else
			{
    
    
				tail->next = lists[minlog];
				tail = lists[minlog];
				lists[minlog] = lists[minlog]->next;

			}
		}
	}
	return newhead;
}

Supongo que te gusta

Origin blog.csdn.net/Djsnxbjans/article/details/128265929
Recomendado
Clasificación