El proceso de preparación para las entrevistas de codificación genera ansiedad para muchos desarrolladores. Hay tanto material que cubrir y, a menudo, gran parte de él se siente irrelevante para lo que los desarrolladores están haciendo en su trabajo diario, lo que solo aumenta el estrés.
Uno de los resultados de esto es que ahora es común que los desarrolladores pasen semanas revisando cientos de preguntas de entrevistas en sitios como LeetCode. Uno de los puntos más comunes de los desarrolladores de ansiedad con los que he hablado antes de la entrevista es: ¿He resuelto suficientes preguntas de práctica? ¿Podría haber hecho más?
Es por eso que trato de concentrarme en ayudar a los desarrolladores a comprender los patrones subyacentes detrás de cada pregunta, para que no tengan que preocuparse por resolver cientos de problemas y sufrir la fatiga de Leetcode. Si comprende los patrones genéricos, puede usarlos como plantilla para resolver una miríada de otros problemas con ligeras variaciones.
Aquí, he presentado los 14 patrones principales que se pueden usar para resolver cualquier pregunta de la entrevista de codificación, así como también cómo identificar cada patrón y algunas preguntas de ejemplo para cada uno. Esto solo toca la superficie. Recomiendo encarecidamente consultar Grokking the Coding Interview: Patterns for Coding Questions para obtener explicaciones completas, ejemplos y prácticas de codificación.
Los siguientes patrones asumen que ha repasado las estructuras de datos. Si no lo ha hecho, consulte estos cursos de actualización sobre estructuras de datos .
¡Empecemos!
1. Ventana corrediza
El patrón de ventana deslizante se usa para realizar una operación requerida en un tamaño de ventana específico de una matriz determinada o una lista vinculada, como encontrar la subarreglo más larga que contiene todos los 1. Las ventanas deslizantes comienzan desde el primer elemento y continúan desplazándose hacia la derecha un elemento y ajustan la longitud de la ventana de acuerdo con el problema que está resolviendo. En algunos casos, el tamaño de la ventana permanece constante y en otros casos, el tamaño crece o se reduce.
Las siguientes son algunas formas en que puede identificar que el problema dado podría requerir una ventana deslizante :
Problemas comunes con los que usa el patrón de ventana deslizante:
2. Dos punteros o iteradores
Two Pointers es un patrón en el que dos punteros iteran a través de la estructura de datos en tándem hasta que uno o ambos punteros alcanzan una determinada condición. Two Pointers suele ser útil cuando se buscan pares en una matriz ordenada o una lista vinculada; por ejemplo, cuando tiene que comparar cada elemento de una matriz con sus otros elementos.
Se necesitan dos punteros porque con solo el puntero, tendría que recorrer continuamente la matriz para encontrar la respuesta. Este ir y venir con un solo iterador es ineficiente para la complejidad del tiempo y el espacio, un concepto denominado análisis asintótico. Si bien la fuerza bruta o la solución ingenua con 1 puntero funcionaría, producirá algo similar a O (n²). En muchos casos, dos indicadores pueden ayudarlo a encontrar una solución con mejor espacio o complejidad de tiempo de ejecución.
Formas de identificar cuándo usar el método Two Pointer:
Aquí hay algunos problemas que presentan el patrón de dos punteros:
3. Punteros rápidos y lentos
El enfoque de puntero rápido y lento, también conocido como el algoritmo Hare & Tortoise , es un algoritmo de puntero que utiliza dos punteros que se mueven a través de la matriz (o secuencia/lista enlazada) a diferentes velocidades. Este enfoque es bastante útil cuando se trata de listas o matrices cíclicas enlazadas.
Al moverse a diferentes velocidades (digamos, en una lista cíclica enlazada), el algoritmo prueba que los dos punteros están obligados a encontrarse. El puntero rápido debería atrapar al puntero lento una vez que ambos punteros estén en un bucle cíclico.
¿Cómo identifica cuándo usar el patrón Rápido y Lento?
¿Cuándo debo usarlo sobre el método Two Pointer mencionado anteriormente?
Problemas con el patrón de punteros rápidos y lentos:
4. Combinar intervalos
El patrón Merge Intervals es una técnica eficiente para manejar intervalos superpuestos. En muchos problemas que involucran intervalos, debe encontrar intervalos superpuestos o fusionar intervalos si se superponen. El patrón funciona así:
Dados dos intervalos ('a' y 'b'), habrá seis formas diferentes en que los dos intervalos pueden relacionarse entre sí:
Comprender y reconocer estos seis casos lo ayudará a resolver una amplia gama de problemas, desde la inserción de intervalos hasta la optimización de fusiones de intervalos.
¿Cómo identifica cuándo usar el patrón Merge Intervals?
Combinar patrones de problemas de intervalo:
5. Clasificación cíclica
Este patrón describe un enfoque interesante para tratar problemas que involucran arreglos que contienen números en un rango dado. El patrón Ordenación cíclica itera sobre el arreglo un número a la vez, y si el número actual que está iterando no está en el índice correcto, lo intercambia con el número en su índice correcto. Puede intentar colocar el número en su índice correcto, pero esto producirá una complejidad de O (n ^ 2) que no es óptima, de ahí el patrón de clasificación cíclica.
¿Cómo identifico este patrón?
Problemas que presentan un patrón de ordenación cíclica:
6. Inversión en el lugar de la lista enlazada
En muchos problemas, se le puede pedir que invierta los enlaces entre un conjunto de nodos de una lista enlazada. A menudo, la restricción es que necesita hacer esto en el lugar, es decir, usando los objetos de nodo existentes y sin usar memoria adicional. Aquí es donde el patrón mencionado anteriormente es útil.
Este patrón invierte un nodo a la vez, comenzando con una variable (actual) que apunta al encabezado de la lista vinculada, y una variable (anterior) apuntará al nodo anterior que haya procesado. De manera escalonada, invertirá el nodo actual apuntándolo al anterior antes de pasar al siguiente nodo. Además, actualizará la variable "anterior" para que siempre apunte al nodo anterior que ha procesado.
¿Cómo identifico cuándo usar este patrón?
Problemas que presentan la inversión en el lugar del patrón de lista enlazada:
7. Árbol BFS
Este patrón se basa en la técnica Breadth First Search (BFS) para atravesar un árbol y utiliza una cola para realizar un seguimiento de todos los nodos de un nivel antes de pasar al siguiente nivel. Cualquier problema que involucre el recorrido de un árbol en un orden de nivel por nivel puede resolverse de manera eficiente utilizando este enfoque.
El patrón Tree BFS funciona empujando el nodo raíz a la cola y luego iterando continuamente hasta que la cola está vacía. Para cada iteración, eliminamos el nodo al principio de la cola y "visitamos" ese nodo. Después de eliminar cada nodo de la cola, también insertamos todos sus elementos secundarios en la cola.
Cómo identificar el patrón Tree BFS:
Problemas con el patrón Tree BFS:
8. Árbol DFS
Tree DFS se basa en la técnica Depth First Search (DFS) para atravesar un árbol.
Puede usar la recursión (o una pila para el enfoque iterativo) para realizar un seguimiento de todos los nodos anteriores (principales) mientras se atraviesa.
El patrón Tree DFS funciona comenzando en la raíz del árbol, si el nodo no es una hoja, debe hacer tres cosas:
Cómo identificar el patrón Tree DFS:
Problemas con el patrón Tree DFS:
9. Dos montones
En muchos problemas, se nos da un conjunto de elementos tales que podemos dividirlos en dos partes. Para resolver el problema, nos interesa conocer el elemento más pequeño de una parte y el elemento más grande de la otra parte. Este patrón es un enfoque eficiente para resolver tales problemas.
Este patrón utiliza dos montones; Un Min Heap para encontrar el elemento más pequeño y un Max Heap para encontrar el elemento más grande. El patrón funciona almacenando la primera mitad de los números en un Max Heap, esto se debe a que desea encontrar el número más grande en la primera mitad. Luego almacena la segunda mitad de los números en un Min Heap, ya que desea encontrar el número más pequeño en la segunda mitad. En cualquier momento, la mediana de la lista actual de números se puede calcular a partir del elemento superior de los dos montones.
Formas de identificar el patrón Two Heaps:
Problemas que presentan
10. Subconjuntos
Una gran cantidad de problemas de entrevistas de codificación implican tratar con permutaciones y combinaciones de un conjunto dado de elementos. Los subconjuntos de patrones describen un enfoque eficiente de Breadth First Search (BFS) para manejar todos estos problemas.
El patrón se ve así:
Dado un conjunto de [1, 5, 3]
Aquí hay una representación visual del patrón Subconjuntos:
Cómo identificar el patrón Subconjuntos:
Problemas con el patrón de subconjuntos:
11. Búsqueda binaria modificada
Cada vez que se le proporciona una matriz ordenada, una lista vinculada o una matriz, y se le pide que encuentre un elemento determinado, el mejor algoritmo que puede usar es la búsqueda binaria. Este patrón describe una manera eficiente de manejar todos los problemas relacionados con la búsqueda binaria.
Los patrones se ven así para un conjunto de orden ascendente:
Aquí hay una representación visual del patrón de búsqueda binaria modificada:
Problemas con el patrón de búsqueda binaria modificada:
Búsqueda binaria independiente del orden (fácil) Búsqueda en una matriz infinita ordenada (media)
12. Los mejores elementos K
Cualquier problema que nos pida encontrar los elementos 'K' superiores/más pequeños/frecuentes entre un conjunto dado cae bajo este patrón.
La mejor estructura de datos para realizar un seguimiento de los elementos 'K' es Heap. Este patrón hará uso del Heap para resolver múltiples problemas relacionados con elementos 'K' a la vez a partir de un conjunto de elementos dados. El patrón se ve así:
No hay necesidad de un algoritmo de clasificación porque el montón hará un seguimiento de los elementos por usted.
Cómo identificar el patrón Elementos 'K' principales:
Problemas con el patrón Top 'K' Elements:
13. Fusión K-way
K-way Merge lo ayuda a resolver problemas que involucran un conjunto de matrices ordenadas.
Cada vez que recibe matrices ordenadas 'K', puede usar un Heap para realizar de manera eficiente un recorrido ordenado de todos los elementos de todas las matrices. Puede insertar el elemento más pequeño de cada matriz en un Min Heap para obtener el mínimo general. Después de obtener el mínimo general, empuje el siguiente elemento de la misma matriz al montón. Luego, repita este proceso para hacer un recorrido ordenado de todos los elementos.
El patrón se ve así:
Cómo identificar el patrón de fusión de K-way:
Problemas que presentan el patrón de fusión K-way:
14. Clasificación topológica
La ordenación topológica se utiliza para encontrar una ordenación lineal de elementos que tienen dependencias entre sí. Por ejemplo, si el evento 'B' depende del evento 'A', 'A' viene antes que 'B' en el ordenamiento topológico.
Este patrón define una manera fácil de comprender la técnica para realizar la ordenación topológica de un conjunto de elementos.
El patrón funciona así:
Cómo identificar el patrón de clasificación topológica:
Problemas que presentan el patrón de clasificación topológica:
¿Qué sigue?
¿Experimenta la fatiga de LeetCode? Aprende estos 14 patrones y tendrás una imagen más completa de cómo abordar un problema sin importar la pregunta.
Si está interesado en una inmersión más profunda a través de los patrones anteriores o los problemas de ejemplo debajo de cada uno, consulte Grokking the Coding Interview: Patterns for Coding Questions . Es el curso más reciente de la serie de entrevistas de Grokking, utilizado por más de 20 000 estudiantes para conseguir empleos en las principales empresas tecnológicas.
El mayor respaldo que puedo darle es que realmente desearía que existiera cuando todavía me estaba preparando para codificar entrevistas.