Este módulo forma parte del repositorio “Guía de Algoritmos y Estructuras de Datos” y está diseñado para ayudarte a mejorar tus habilidades de lógica de programación, algoritmia y manipulación de estructuras de datos. Los ejercicios aquí incluidos cubren conceptos fundamentales, como la manipulación de cadenas, el uso de operaciones matemáticas, la búsqueda y ordenamiento, y técnicas avanzadas como la programación dinámica.
Objetivo: Crear una función que invierta una cadena de texto.
// JavaScript
function reverseString(str) {
// Solución 1: Usando métodos de array
return str.split('').reverse().join('');
// Solución 2: Usando un bucle
let reversed = '';
for (let i = str.length - 1; i >= 0; i--) {
reversed += str[i];
}
return reversed;
}
// Test
console.log(reverseString("hello")); // "olleh"
# Python
def reverse_string(s: str) -> str:
# Solución 1: Usando slice
return s[::-1]
# Solución 2: Usando un bucle
reversed_str = ""
for char in s:
reversed_str = char + reversed_str
return reversed_str
# Test
print(reverse_string("hello")) # "olleh"
Objetivo: Determinar si una cadena es un palíndromo (se lee igual al derecho y al revés).
// JavaScript
function isPalindrome(str) {
// Normalizar la cadena: remover espacios y convertir a minúsculas
str = str.toLowerCase().replace(/[^a-z0-9]/g, '');
// Comparar la cadena con su reverso
return str === str.split('').reverse().join('');
}
// Tests
console.log(isPalindrome("A man, a plan, a canal: Panama")); // true
console.log(isPalindrome("race a car")); // false
# Python
def is_palindrome(s: str) -> bool:
# Normalizar la cadena
s = ''.join(char.lower() for char in s if char.isalnum())
# Comparar la cadena con su reverso
return s == s[::-1]
# Tests
print(is_palindrome("A man, a plan, a canal: Panama")) # True
print(is_palindrome("race a car")) # False
Objetivo: Encontrar la longitud de la subcadena más larga sin caracteres que se repitan.
// JavaScript
function lengthOfLongestSubstring(s) {
let maxLength = 0;
let start = 0;
const charMap = new Map();
for (let end = 0; end < s.length; end++) {
if (charMap.has(s[end])) {
start = Math.max(start, charMap.get(s[end]) + 1);
}
charMap.set(s[end], end);
maxLength = Math.max(maxLength, end - start + 1);
}
return maxLength;
}
// Tests
console.log(lengthOfLongestSubstring("abcabcbb")); // 3
console.log(lengthOfLongestSubstring("bbbbb")); // 1
# Python
def length_of_longest_substring(s: str) -> int:
char_map = {}
max_length = start = 0
for end, char in enumerate(s):
if char in char_map:
start = max(start, char_map[char] + 1)
char_map[char] = end
max_length = max(max_length, end - start + 1)
return max_length
# Tests
print(length_of_longest_substring("abcabcbb")) # 3
print(length_of_longest_substring("bbbbb")) # 1
Objetivo: Determinar si un número es primo.
// JavaScript
function isPrime(num) {
if (num <= 1) return false;
if (num <= 3) return true;
// Verificar divisibilidad hasta la raíz cuadrada
for (let i = 2; i <= Math.sqrt(num); i++) {
if (num % i === 0) return false;
}
return true;
}
// Tests
console.log(isPrime(17)); // true
console.log(isPrime(4)); // false
# Python
def is_prime(num: int) -> bool:
if num <= 1:
return False
if num <= 3:
return True
# Verificar divisibilidad hasta la raíz cuadrada
for i in range(2, int(num ** 0.5) + 1):
if num % i == 0:
return False
return True
# Tests
print(is_prime(17)) # True
print(is_prime(4)) # False
Objetivo: Generar los primeros n números de la secuencia de Fibonacci.
// JavaScript
function fibonacci(n) {
// Solución iterativa
const fib = [0, 1];
for (let i = 2; i < n; i++) {
fib[i] = fib[i-1] + fib[i-2];
}
return fib.slice(0, n);
// Solución recursiva (menos eficiente)
if (n <= 0) return [];
if (n === 1) return [0];
if (n === 2) return [0, 1];
const seq = fibonacci(n - 1);
seq.push(seq[seq.length - 1] + seq[seq.length - 2]);
return seq;
}
// Test
console.log(fibonacci(8)); // [0, 1, 1, 2, 3, 5, 8, 13]
# Python
def fibonacci(n: int) -> list:
# Solución iterativa
fib = [0, 1]
for i in range(2, n):
fib.append(fib[i-1] + fib[i-2])
return fib[:n]
# Solución con generador
def fib_gen(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
return list(fib_gen(n))
# Test
print(fibonacci(8)) # [0, 1, 1, 2, 3, 5, 8, 13]
Objetivo: Encontrar el número más grande y más pequeño en una lista.
// JavaScript
function findMinMax(arr) {
if (!arr.length) return null;
return {
min: Math.min(...arr),
max: Math.max(...arr)
};
// Solución alternativa sin métodos nativos
let min = arr[0];
let max = arr[0];
for (let num of arr) {
if (num < min) min = num;
if (num > max) max = num;
}
return { min, max };
}
// Test
console.log(findMinMax([1, 5, 3, 2, 4])); // { min: 1, max: 5 }
# Python
def find_min_max(arr: list) -> dict:
if not arr:
return None
# Solución usando funciones nativas
return {
'min': min(arr),
'max': max(arr)
}
# Solución manual
min_val = max_val = arr[0]
for num in arr:
if num < min_val:
min_val = num
if num > max_val:
max_val = num
return {'min': min_val, 'max': max_val}
# Test
print(find_min_max([1, 5, 3, 2, 4])) # {'min': 1, 'max': 5}
Objetivo: Calcular de cuántas formas diferentes se pueden subir n escalones si se pueden subir 1 o 2 escalones a la vez.
// JavaScript
function climbStairs(n) {
if (n <= 2) return n;
// Solución con programación dinámica
let dp = new Array(n + 1);
dp[1] = 1;
dp[2] = 2;
for (let i = 3; i <= n; i++) {
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
// Tests
console.log(climbStairs(3)); // 3
console.log(climbStairs(4)); // 5
# Python
def climb_stairs(n: int) -> int:
if n <= 2:
return n
# Solución con programación dinámica
dp = [0] * (n + 1)
dp[1] = 1
dp[2] = 2
for i in range(3, n + 1):
dp[i] = dp[i-1] + dp[i-2]
return dp[n]
# Tests
print(climb_stairs(3)) # 3
print(climb_stairs(4)) # 5