Problemas de Listas Enlazadas en LeetCode

Este problema se puede resolver con dos enfoques distintos. El primero consiste en modificar la lista enlazada original. Utilizamos dos punteros: uno para recorrer la lista y otro para mantener el nodo anterior.


struct Nodo* eliminarElementos(struct Nodo* cabeza, int valor) {
    struct Nodo* anterior = NULL;
    struct Nodo* actual = cabeza;
    while(actual)
    {
        if(actual->valor == valor)
        {
            if(anterior == NULL)
            {
                cabeza = cabeza->siguiente;
                actual = actual->siguiente;
            }
            else
            {
                struct Nodo* temp = actual;
                actual = actual->siguiente;
                free(temp);
                anterior->siguiente = actual;
            }
              
        }
        else
        {
            anterior = actual;
            actual = actual->siguiente;
        }
    }
    return cabeza;
}

El segundo enfoque utiliza la técnica de inserción en la cola para crear una nueva lista enlazada:


struct Nodo* eliminarElementos(struct Nodo* cabeza, int valor) {
    struct Nodo* nuevacabeza = NULL, *cola = NULL;
    struct Nodo* actual = cabeza;
    while(actual)
    {
        if(actual->valor == valor)
        {
            actual = actual->siguiente;
        }
        else
        {
            if(nuevacabeza == NULL)
            {
                nuevacabeza = actual;
                cola = nuevacabeza;
            }
            else
            {
                cola->siguiente = actual;
                cola = cola ->siguiente;
            }
            actual =  actual->siguiente;
        }
    }
    if(cola)
        cola->siguiente = NULL;
    return nuevacabeza;
}

Invertir una Lista Enlazada

Este problema tiene dos soluciones comunes. La primera utiliza tres punteros para ivnertir los enlaces:


struct Nodo* invertirLista(struct Nodo* cabeza) {
    if(cabeza == NULL)    
        return NULL;
    struct Nodo* previo = NULL;
    struct Nodo* actual = cabeza;
    struct Nodo* siguiente = NULL;
    
    while(actual != NULL)
    {
        siguiente = actual->siguiente;
        actual->siguiente = previo;
        previo = actual;
        actual = siguiente;
    }
    return previo;
}

La segunda solución utiliza el método de inserción en la cabeza:


struct Nodo* invertirLista(struct Nodo* cabeza) {
    struct Nodo* nuevacabeza = NULL;
    struct Nodo* actual = cabeza;
    while(actual)
    {
        struct Nodo* temp = actual->siguiente;
        actual->siguiente = nuevacabeza;
        nuevacabeza = actual;
        actual = temp;
    }
    return nuevacabeza;
}

Encontrar el Nodo Medio de una Lista Enlazada

Este problema se resuelve eficientemente con el algoritmo de punteros rápidos y lentos:


struct Nodo* nodoMedio(struct Nodo* cabeza) {
    struct Nodo* rapido = cabeza;
    struct Nodo* lento = cabeza;
    while(rapido && rapido->siguiente)
    {
        rapido = rapido->siguiente->siguiente;
        lento = lento->siguiente;
    }
    return lento;
}

Encontrar el K-ésimo Nodo desde el Final

Utilizando una modificación del algoritmo de punteros rápidos y lentos:


struct Nodo* encontrarKDesdeFinal(struct Nodo* pListHead, int k) {
    struct Nodo*lento = pListHead;
    struct Nodo*rapido = pListHead;
     
    while(k-- > 0)
    {
        if(rapido == NULL)
            return NULL;
        rapido = rapido->siguiente;
    }
    while(rapido)
    {
        rapido = rapido->siguiente;
        lento = lento->siguiente;
    }
    return lento;
}

Combinar Dos Listas Enlazadas Ordenadas

Este problema se resuelve comparando nodos de ambas listas y construyendo una nueva lista enlazada ordenada:


struct Nodo* combinarDosListas(struct Nodo* lista1, struct Nodo* lista2) {
    if(lista1 == NULL && lista2 == NULL)
    {
        return NULL;
    }
    
    struct Nodo* actual1 = lista1;
    struct Nodo* actual2 = lista2;
    struct Nodo* nuevacabeza = NULL;
    struct Nodo* cola = NULL;
    
    while(actual1 && actual2)
    {
        if(actual1->valor < actual2->valor)
        {
            if(nuevacabeza == NULL)
            {
                nuevacabeza = cola = actual1;
            }
            else
            {
                cola->siguiente = actual1;
                cola = cola->siguiente;
            }
            actual1 = actual1->siguiente;
        }
        else
        {
            if(nuevacabeza == NULL)
            {
                nuevacabeza = cola = actual2;
            }
            else
            {
                cola->siguiente = actual2;
                cola = cola->siguiente;
            }
            actual2 = actual2->siguiente;
        }
    }
    
    // Agregar los nodos restantes
    if(actual1)
        cola->siguiente = actual1;
    else if(actual2)
        cola->siguiente = actual2;
    
    return nuevacabeza;
}

La clave para resolver estos problemas es practicar con diagramas y recorrer manualmente el código con diferentes casos de prueba.

Etiquetas: Listas Enlazadas algoritmos estructuras de datos leetcode Punteros

Publicado el 6-9 03:26