Skip to content

Commit 6d42ed3

Browse files
committed
feat: add articles to normal challenges
1 parent 6274f55 commit 6d42ed3

File tree

10 files changed

+888
-0
lines changed

10 files changed

+888
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Challenge Description and Solution
2+
3+
## English Version
4+
5+
### Challenge Description
6+
Implement a binary search tree (BST) that supports insertions, searches, and deletions. Test different traversals (in-order, pre-order, and post-order) to ensure the tree updates correctly.
7+
8+
### Code Explanation
9+
The BST is implemented with a `Node` class representing each node and a `BinarySearchTree` class managing the tree. The tree supports:
10+
- `insert(key)`: Inserts a key into the BST.
11+
- `search(key)`: Searches for a key in the BST.
12+
- `delete(key)`: Deletes a key from the BST.
13+
- Traversal methods: `inorder()`, `preorder()`, and `postorder()` return lists of keys in respective traversal orders.
14+
15+
The deletion handles three cases:
16+
- Node with no children.
17+
- Node with one child.
18+
- Node with two children (replaces with inorder successor).
19+
20+
### Relevant Code Snippets
21+
22+
```python
23+
class Node:
24+
def __init__(self, key):
25+
self.key = key
26+
self.left = None
27+
self.right = None
28+
29+
class BinarySearchTree:
30+
def __init__(self):
31+
self.root = None
32+
33+
def insert(self, key):
34+
if self.root is None:
35+
self.root = Node(key)
36+
else:
37+
self._insert(self.root, key)
38+
39+
def _insert(self, root, key):
40+
if key < root.key:
41+
if root.left is None:
42+
root.left = Node(key)
43+
else:
44+
self._insert(root.left, key)
45+
else:
46+
if root.right is None:
47+
root.right = Node(key)
48+
else:
49+
self._insert(root.right, key)
50+
```
51+
52+
### Historical Context
53+
Binary Search Trees are fundamental data structures in computer science, used to maintain sorted data and allow efficient insertion, deletion, and lookup operations. They form the basis for more advanced balanced trees like AVL and Red-Black trees.
54+
55+
---
56+
57+
## Versión en Español
58+
59+
### Descripción del Reto
60+
Implementa un árbol binario de búsqueda (BST) que soporte inserciones, búsquedas y eliminaciones. Prueba diferentes recorridos (inorden, preorden y postorden) para asegurar que el árbol se actualice correctamente.
61+
62+
### Explicación del Código
63+
El BST se implementa con una clase `Node` que representa cada nodo y una clase `BinarySearchTree` que maneja el árbol. El árbol soporta:
64+
- `insert(key)`: Inserta una clave en el BST.
65+
- `search(key)`: Busca una clave en el BST.
66+
- `delete(key)`: Elimina una clave del BST.
67+
- Métodos de recorrido: `inorder()`, `preorder()` y `postorder()` que retornan listas de claves en los respectivos órdenes de recorrido.
68+
69+
La eliminación maneja tres casos:
70+
- Nodo sin hijos.
71+
- Nodo con un hijo.
72+
- Nodo con dos hijos (se reemplaza con el sucesor en inorden).
73+
74+
### Fragmentos de Código Relevantes
75+
76+
```python
77+
class Node:
78+
def __init__(self, key):
79+
self.key = key
80+
self.left = None
81+
self.right = None
82+
83+
class BinarySearchTree:
84+
def __init__(self):
85+
self.root = None
86+
87+
def insert(self, key):
88+
if self.root is None:
89+
self.root = Node(key)
90+
else:
91+
self._insert(self.root, key)
92+
93+
def _insert(self, root, key):
94+
if key < root.key:
95+
if root.left is None:
96+
root.left = Node(key)
97+
else:
98+
self._insert(root.left, key)
99+
else:
100+
if root.right is None:
101+
root.right = Node(key)
102+
else:
103+
self._insert(root.right, key)
104+
```
105+
106+
### Contexto Histórico
107+
Los árboles binarios de búsqueda son estructuras de datos fundamentales en la informática, utilizadas para mantener datos ordenados y permitir inserciones, eliminaciones y búsquedas eficientes. Forman la base para árboles balanceados más avanzados como AVL y Red-Black.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Challenge Description and Solution
2+
3+
## English Version
4+
5+
### Challenge Description
6+
Given an array of numbers, create a function that returns the k elements that appear most frequently. Consider using data structures like hash maps and heaps to efficiently manage frequency. Provide two variants using OOP: one with hash map and sorting, and another with hash map and heap.
7+
8+
### Code Explanation
9+
The solution provides two classes:
10+
11+
- `TopKFrequentHashMap`: Uses a hash map (Counter) to count frequencies and sorts the items by frequency in descending order to return the top k elements.
12+
- `TopKFrequentHeap`: Uses a hash map (Counter) and a heap (priority queue) to efficiently retrieve the top k elements with the highest frequency.
13+
14+
### Relevant Code Snippets
15+
16+
```python
17+
from collections import Counter
18+
19+
class TopKFrequentHashMap:
20+
def __init__(self, nums):
21+
self.nums = nums
22+
23+
def top_k_frequent(self, k):
24+
count = Counter(self.nums)
25+
sorted_items = sorted(count.items(), key=lambda x: x[1], reverse=True)
26+
return [item[0] for item in sorted_items[:k]]
27+
```
28+
29+
```python
30+
from collections import Counter
31+
import heapq
32+
33+
class TopKFrequentHeap:
34+
def __init__(self, nums):
35+
self.nums = nums
36+
37+
def top_k_frequent(self, k):
38+
count = Counter(self.nums)
39+
return [item for item, freq in heapq.nlargest(k, count.items(), key=lambda x: x[1])]
40+
```
41+
42+
### Historical Context
43+
Finding the top k frequent elements is a common problem in data analysis and information retrieval. Using hash maps for frequency counting and heaps for efficient retrieval are standard techniques in algorithm design.
44+
45+
---
46+
47+
## Versión en Español
48+
49+
### Descripción del Reto
50+
Dado un arreglo de números, crea una función que devuelva los k elementos que aparecen con mayor frecuencia. Considera usar estructuras de datos como mapas hash y montículos para gestionar eficientemente la frecuencia. Proporciona dos variantes usando POO: una con mapa hash y ordenamiento, y otra con mapa hash y montículo.
51+
52+
### Explicación del Código
53+
La solución proporciona dos clases:
54+
55+
- `TopKFrequentHashMap`: Usa un mapa hash (Counter) para contar frecuencias y ordena los elementos por frecuencia en orden descendente para devolver los k elementos principales.
56+
- `TopKFrequentHeap`: Usa un mapa hash (Counter) y un montículo (cola de prioridad) para obtener eficientemente los k elementos con mayor frecuencia.
57+
58+
### Fragmentos de Código Relevantes
59+
60+
```python
61+
from collections import Counter
62+
63+
class TopKFrequentHashMap:
64+
def __init__(self, nums):
65+
self.nums = nums
66+
67+
def top_k_frequent(self, k):
68+
count = Counter(self.nums)
69+
sorted_items = sorted(count.items(), key=lambda x: x[1], reverse=True)
70+
return [item[0] for item in sorted_items[:k]]
71+
```
72+
73+
```python
74+
from collections import Counter
75+
import heapq
76+
77+
class TopKFrequentHeap:
78+
def __init__(self, nums):
79+
self.nums = nums
80+
81+
def top_k_frequent(self, k):
82+
count = Counter(self.nums)
83+
return [item for item, freq in heapq.nlargest(k, count.items(), key=lambda x: x[1])]
84+
```
85+
86+
### Contexto Histórico
87+
Encontrar los k elementos más frecuentes es un problema común en análisis de datos y recuperación de información. Usar mapas hash para contar frecuencias y montículos para recuperación eficiente son técnicas estándar en el diseño de algoritmos.
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Challenge Description and Solution
2+
3+
## English Version
4+
5+
### Challenge Description
6+
Develop a function that implements the Merge Sort algorithm to sort an array. Evaluate the efficiency of your implementation and consider cases with large arrays.
7+
8+
### Code Explanation
9+
Merge Sort is a divide-and-conquer algorithm that divides the array into halves, recursively sorts each half, and then merges the sorted halves.
10+
11+
The `merge_sort` function recursively splits the array until subarrays have one element. The `merge` function then combines two sorted arrays into one sorted array.
12+
13+
### Relevant Code Snippets
14+
15+
```python
16+
def merge_sort(arr):
17+
if len(arr) <= 1:
18+
return arr
19+
20+
mid = len(arr) // 2
21+
left = merge_sort(arr[:mid])
22+
right = merge_sort(arr[mid:])
23+
24+
return merge(left, right)
25+
26+
def merge(left, right):
27+
result = []
28+
i = j = 0
29+
30+
while i < len(left) and j < len(right):
31+
if left[i] < right[j]:
32+
result.append(left[i])
33+
i += 1
34+
else:
35+
result.append(right[j])
36+
j += 1
37+
38+
result.extend(left[i:])
39+
result.extend(right[j:])
40+
return result
41+
```
42+
43+
### Historical Context
44+
Merge Sort was invented by John von Neumann in 1945. It is one of the earliest sorting algorithms and is notable for its stable sorting and O(n log n) time complexity, making it efficient for large datasets.
45+
46+
---
47+
48+
## Versión en Español
49+
50+
### Descripción del Reto
51+
Desarrolla una función que implemente el algoritmo Merge Sort para ordenar un arreglo. Evalúa la eficiencia de tu implementación y considera casos con arreglos grandes.
52+
53+
### Explicación del Código
54+
Merge Sort es un algoritmo de divide y vencerás que divide el arreglo en mitades, ordena recursivamente cada mitad y luego combina las mitades ordenadas.
55+
56+
La función `merge_sort` divide recursivamente el arreglo hasta que los subarreglos tienen un elemento. La función `merge` combina dos arreglos ordenados en uno solo ordenado.
57+
58+
### Fragmentos de Código Relevantes
59+
60+
```python
61+
def merge_sort(arr):
62+
if len(arr) <= 1:
63+
return arr
64+
65+
mid = len(arr) // 2
66+
left = merge_sort(arr[:mid])
67+
right = merge_sort(arr[mid:])
68+
69+
return merge(left, right)
70+
71+
def merge(left, right):
72+
result = []
73+
i = j = 0
74+
75+
while i < len(left) and j < len(right):
76+
if left[i] < right[j]:
77+
result.append(left[i])
78+
i += 1
79+
else:
80+
result.append(right[j])
81+
j += 1
82+
83+
result.extend(left[i:])
84+
result.extend(right[j:])
85+
return result
86+
```
87+
88+
### Contexto Histórico
89+
Merge Sort fue inventado por John von Neumann en 1945. Es uno de los algoritmos de ordenamiento más antiguos y es conocido por su ordenamiento estable y complejidad temporal O(n log n), lo que lo hace eficiente para grandes conjuntos de datos.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Challenge Description and Solution
2+
3+
## English Version
4+
5+
### Challenge Description
6+
Given a string, find the length of the longest substring without repeating characters. Use sliding window techniques to optimize the solution's performance.
7+
8+
### Code Explanation
9+
The solution uses a sliding window approach with two pointers (`left` and `right`) and a dictionary to track the last index of each character. When a repeated character is found within the current window, the left pointer moves to the right of the previous occurrence to maintain a substring without duplicates.
10+
11+
The function returns both the length and the longest substring without repeating characters.
12+
13+
### Relevant Code Snippet
14+
15+
```python
16+
def length_of_longest_substring(s):
17+
char_index_map = {}
18+
left = 0
19+
max_length = 0
20+
max_substring = ""
21+
22+
for right in range(len(s)):
23+
if s[right] in char_index_map and char_index_map[s[right]] >= left:
24+
left = char_index_map[s[right]] + 1
25+
char_index_map[s[right]] = right
26+
if right - left + 1 > max_length:
27+
max_length = right - left + 1
28+
max_substring = s[left:right+1]
29+
30+
return max_length, max_substring
31+
```
32+
33+
### Historical Context
34+
The sliding window technique is a common approach in algorithm design to solve problems involving contiguous sequences efficiently. This problem is a classic example often asked in coding interviews to test understanding of hash maps and two-pointer techniques.
35+
36+
---
37+
38+
## Versión en Español
39+
40+
### Descripción del Reto
41+
Dada una cadena, encuentra la longitud de la subcadena más larga sin caracteres repetidos. Usa técnicas de ventana deslizante para optimizar el rendimiento de la solución.
42+
43+
### Explicación del Código
44+
La solución utiliza un enfoque de ventana deslizante con dos punteros (`left` y `right`) y un diccionario para rastrear el último índice de cada carácter. Cuando se encuentra un carácter repetido dentro de la ventana actual, el puntero izquierdo se mueve a la derecha de la ocurrencia previa para mantener una subcadena sin duplicados.
45+
46+
La función retorna tanto la longitud como la subcadena más larga sin caracteres repetidos.
47+
48+
### Fragmento de Código Relevante
49+
50+
```python
51+
def length_of_longest_substring(s):
52+
char_index_map = {}
53+
left = 0
54+
max_length = 0
55+
max_substring = ""
56+
57+
for right in range(len(s)):
58+
if s[right] in char_index_map and char_index_map[s[right]] >= left:
59+
left = char_index_map[s[right]] + 1
60+
char_index_map[s[right]] = right
61+
if right - left + 1 > max_length:
62+
max_length = right - left + 1
63+
max_substring = s[left:right+1]
64+
65+
return max_length, max_substring
66+
```
67+
68+
### Contexto Histórico
69+
La técnica de ventana deslizante es un enfoque común en el diseño de algoritmos para resolver problemas que involucran secuencias contiguas de manera eficiente. Este problema es un ejemplo clásico que se pregunta frecuentemente en entrevistas técnicas para evaluar el entendimiento de mapas hash y técnicas de dos punteros.

0 commit comments

Comments
 (0)