Sword se refiere a la copia de la oferta 35 de una lista enlazada compleja

Copiar listas enlazadas complejas


Esta pregunta requiere que copiemos una lista vinculada compleja. En una lista vinculada compleja, además de un puntero siguiente que apunta al siguiente nodo, cada nodo también tiene un puntero aleatorio que apunta a cualquier nodo en la lista vinculada o nulo.

Ejemplo 1 La siguiente figura es una lista enlazada compleja con punteros aleatorios. Cada nodo está representado por una lista de longitud 2. El primer elemento representa el valor del nodo actual y el segundo elemento representa el índice del elemento señalado por el puntero aleatorio (si apunta a nulo, se registra como nulo). ). Entonces la siguiente lista enlazada compleja se puede registrar como:

Insertar descripción de la imagen aquí

[[7, nulo], [13, 0], [11, 4], [10, 2], [1, 0]]

Es necesario copiar la lista vinculada compleja y la salida y la entrada deben ser las mismas, que sigue siendo:

[[7, nulo], [13, 0], [11, 4], [10, 2], [1, 0]]

Método 1 Retroceso + Tabla Hash

Esta pregunta requiere que hagamos una copia profunda de una lista vinculada especial. Si se trata de una lista vinculada ordinaria, podemos crear directamente nodos de lista vinculada en el orden de recorrido. En esta pregunta, debido a la existencia de punteros aleatorios, cuando copiamos un nodo, es posible que el nodo señalado por el puntero aleatorio del nodo actual aún no se haya creado, por lo que debemos cambiar nuestra forma de pensar.

Una solución factible es que utilicemos el retroceso para hacer que las operaciones de copia de cada nodo sean independientes entre sí. Para el nodo actual, primero debemos copiarlo, luego copiamos el nodo sucesor del nodo actual y el nodo señalado por el puntero aleatorio del nodo actual. Una vez completada la copia, el puntero del nuevo nodo creado aparecerá se devolverá y se podrán completar los dos punteros del nodo actual.

Específicamente, utilizamos una tabla hash para registrar la creación de nuevos nodos correspondientes a cada nodo. Mientras recorremos la lista vinculada, verificamos la creación del nodo sucesor del nodo actual y el nodo al que apunta el puntero aleatorio del nodo actual. Si no se ha creado un nuevo nodo para cualquiera de estos dos nodos, lo crearemos de forma recursiva inmediatamente. Cuando completamos la copia y rastreamos hasta la capa actual, podemos completar la asignación del puntero del nodo actual.

Tenga en cuenta que muchos otros nodos pueden apuntar a un nodo, por lo que podemos intentar copiar un nodo varias veces de forma recursiva. Para evitar copias repetidas, primero debemos verificar si el nodo actual se ha copiado. Si se ha copiado , podemos copiarlo directamente desde Ha. Simplemente saque el puntero del nodo copiado de la tabla hash y devuélvalo.

En el código real, necesitamos determinar específicamente cuándo un nodo determinado es un nodo vacío.

segunda explicación

Utilice las características de consulta de la tabla hash, considere construir la relación de mapeo de pares clave-valor entre el nodo de la lista vinculada original y el nodo correspondiente de la nueva lista vinculada, y luego recorra y construya los puntos de referencia siguientes y aleatorios de cada nodo de la nueva lista enlazada.

Proceso algorítmico:

1. Si el encabezado del nodo principal es un nodo vacío, se devolverá nulo directamente.

2. Inicialización: tabla hash dic, el nodo cur apunta al nodo principal

3. Copie la lista vinculada:

  • Cree un nuevo nodo y agregue pares clave-valor a dic (nodo cur original, nodo cur nuevo)
  • Cur atraviesa al siguiente nodo de la lista enlazada original.

4. Construya el punto de referencia de la nueva lista vinculada.

  • Construya las referencias siguientes y aleatorias del nuevo nodo al que apuntar.
  • Cur atraviesa al siguiente nodo de la lista enlazada original.

Método 2: empalmar + dividir

Considere la 原节点1->新节点1->原节点2->新节点2->......lista enlazada empalmada construida, de modo que randompueda encontrar el nodo señalador correspondiente al nuevo nodo al acceder randomal nodo señalador del nodo original.

Proceso algorítmico

1. Copie cada nodo y cree una lista enlazada de empalme

  • Supongamos que la lista enlazada original es nodo1->nodo2->..., y la lista enlazada empalmada construida es la siguiente:
    • nodo1->nodo1_nuevo -> nodo2->nodo2_nuevo ->…

2. Construya puntos aleatorios para cada nodo de la nueva lista vinculada.

  • Al acceder al nodo señalador aleatorio cur->random de cur del nodo original, el nodo señalador aleatorio correspondiente al nuevo nodo cur.next es cur->random->next;

3. Divida la lista enlazada original/nueva

  • Configure pre/cur para que apunte al nodo principal de la lista enlazada original/nueva respectivamente, recorra y ejecute pre->next = pre->next->next y cur->next = cur->next->next, y divida las dos listas enlazadas.

4. Devuelva la resolución del nodo principal de la nueva lista vinculada.

referencias

[1] https://leetcode.cn/problems/fu-za-lian-biao-de-fu-zhi-lcof/solution/jian-zhi-offer-35-fu-za-lian-biao-de-fu -zhi-ha-xi-/

Supongo que te gusta

Origin blog.csdn.net/ChenglinBen/article/details/131208279
Recomendado
Clasificación