Menu iconMenu icon
Introducción a los Algoritmos

Capítulo 4: Tipos de Algoritmos Básicos

4.5 Problemas de práctica

Problema 1: Búsqueda Binaria (Divide y Conquista)

Dada una lista ordenada de n enteros y un entero objetivo x, escribe una función que encuentre la posición de x en la lista usando un algoritmo de búsqueda binaria. Recuerda, la búsqueda binaria opera dividiendo efectivamente el problema a la mitad con cada paso.

Solución:

def binary_search(list, x):
    low = 0
    high = len(list) - 1

    while low <= high:
        mid = (high + low) // 2

        if list[mid] < x:
            low = mid + 1
        elif list[mid] > x:
            high = mid - 1
        else:
            return mid
    return -1

Problema 2: Cambio de Monedas (Algoritmo Voraz)

Dada una lista de denominaciones de monedas y un valor n, escribe una función que calcule el número mínimo de monedas necesarias para hacer cambio por n. Utiliza un algoritmo voraz que siempre selecciona la denominación más grande menor o igual al monto restante a cambiar. Prueba tu función con varios conjuntos de monedas, como las denominaciones estándar de EE. UU. o euros.

Solución:

def coin_change(coins, n):
    coins.sort(reverse=True)
    count = 0
    for coin in coins:
        while n >= coin:
            n -= coin
            count += 1
        if n == 0:
            return count
    return count

Problema 3: Serie Fibonacci (Programación Dinámica)

Escribe una función para calcular el enésimo número de Fibonacci. La serie de Fibonacci se define como: F(0) = 0, F(1) = 1, y F(n) = F(n-1) + F(n-2) para n > 1. Primero, implementa esto usando recursión simple, luego optimiza tu función usando programación dinámica para almacenar y reutilizar valores calculados.

Solución:

def fibonacci(n, computed = {0: 0, 1: 1}):
    if n not in computed:
        computed[n] = fibonacci(n - 1, computed) + fibonacci(n - 2, computed)
    return computed[n]

Problema 4: Suma de Números Naturales (Algoritmo Recursivo)

Escribe una función que calcule la suma de todos los números naturales desde 1 hasta n usando un algoritmo recursivo. Compara la solución recursiva con una solución iterativa y discute las diferencias.

Solución:

def recursive_sum(n):
    if n <= 1:
        return n
    else:
        return n + recursive_sum(n - 1)

def iterative_sum(n):
    return n * (n + 1) // 2

Problema 5: QuickSort (Divide y Conquista)

Implementa el algoritmo QuickSort que ordena una matriz de enteros. QuickSort es un algoritmo de Divide y Conquista. Elige un elemento como pivote y particiona la matriz dada alrededor del pivote seleccionado.

Solución:

def quicksort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quicksort(left) + middle + quicksort(right)

Problema 6: Implementación de una Pila usando Recursión (Algoritmo Recursivo)

Implementa una estructura de datos de pila utilizando recursión. Tu pila debería tener funciones pushpop, y peek.

Solución:

class Stack:
    def __init__(self):
        self.stack = []

    def push(self, item):
        self.stack.append(item)

    def pop(self):
        if len(self.stack) < 1:
            return None
        return self.stack.pop()

    def peek(self):
        if self.stack:
            return self.stack[-1]
        return None

Recuerda, el objetivo de estos problemas prácticos es obtener una comprensión práctica de los diferentes tipos de algoritmos, cómo funcionan y dónde se pueden aplicar. Intenta resolver todos los problemas y compara las soluciones para ver la diferencia entre estos tipos de algoritmos. ¡Buena suerte!

En el próximo capítulo, exploraremos tipos de algoritmos más avanzados y sus aplicaciones en la resolución de problemas del mundo real. ¡Mantente atento!

4.5 Problemas de práctica

Problema 1: Búsqueda Binaria (Divide y Conquista)

Dada una lista ordenada de n enteros y un entero objetivo x, escribe una función que encuentre la posición de x en la lista usando un algoritmo de búsqueda binaria. Recuerda, la búsqueda binaria opera dividiendo efectivamente el problema a la mitad con cada paso.

Solución:

def binary_search(list, x):
    low = 0
    high = len(list) - 1

    while low <= high:
        mid = (high + low) // 2

        if list[mid] < x:
            low = mid + 1
        elif list[mid] > x:
            high = mid - 1
        else:
            return mid
    return -1

Problema 2: Cambio de Monedas (Algoritmo Voraz)

Dada una lista de denominaciones de monedas y un valor n, escribe una función que calcule el número mínimo de monedas necesarias para hacer cambio por n. Utiliza un algoritmo voraz que siempre selecciona la denominación más grande menor o igual al monto restante a cambiar. Prueba tu función con varios conjuntos de monedas, como las denominaciones estándar de EE. UU. o euros.

Solución:

def coin_change(coins, n):
    coins.sort(reverse=True)
    count = 0
    for coin in coins:
        while n >= coin:
            n -= coin
            count += 1
        if n == 0:
            return count
    return count

Problema 3: Serie Fibonacci (Programación Dinámica)

Escribe una función para calcular el enésimo número de Fibonacci. La serie de Fibonacci se define como: F(0) = 0, F(1) = 1, y F(n) = F(n-1) + F(n-2) para n > 1. Primero, implementa esto usando recursión simple, luego optimiza tu función usando programación dinámica para almacenar y reutilizar valores calculados.

Solución:

def fibonacci(n, computed = {0: 0, 1: 1}):
    if n not in computed:
        computed[n] = fibonacci(n - 1, computed) + fibonacci(n - 2, computed)
    return computed[n]

Problema 4: Suma de Números Naturales (Algoritmo Recursivo)

Escribe una función que calcule la suma de todos los números naturales desde 1 hasta n usando un algoritmo recursivo. Compara la solución recursiva con una solución iterativa y discute las diferencias.

Solución:

def recursive_sum(n):
    if n <= 1:
        return n
    else:
        return n + recursive_sum(n - 1)

def iterative_sum(n):
    return n * (n + 1) // 2

Problema 5: QuickSort (Divide y Conquista)

Implementa el algoritmo QuickSort que ordena una matriz de enteros. QuickSort es un algoritmo de Divide y Conquista. Elige un elemento como pivote y particiona la matriz dada alrededor del pivote seleccionado.

Solución:

def quicksort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quicksort(left) + middle + quicksort(right)

Problema 6: Implementación de una Pila usando Recursión (Algoritmo Recursivo)

Implementa una estructura de datos de pila utilizando recursión. Tu pila debería tener funciones pushpop, y peek.

Solución:

class Stack:
    def __init__(self):
        self.stack = []

    def push(self, item):
        self.stack.append(item)

    def pop(self):
        if len(self.stack) < 1:
            return None
        return self.stack.pop()

    def peek(self):
        if self.stack:
            return self.stack[-1]
        return None

Recuerda, el objetivo de estos problemas prácticos es obtener una comprensión práctica de los diferentes tipos de algoritmos, cómo funcionan y dónde se pueden aplicar. Intenta resolver todos los problemas y compara las soluciones para ver la diferencia entre estos tipos de algoritmos. ¡Buena suerte!

En el próximo capítulo, exploraremos tipos de algoritmos más avanzados y sus aplicaciones en la resolución de problemas del mundo real. ¡Mantente atento!

4.5 Problemas de práctica

Problema 1: Búsqueda Binaria (Divide y Conquista)

Dada una lista ordenada de n enteros y un entero objetivo x, escribe una función que encuentre la posición de x en la lista usando un algoritmo de búsqueda binaria. Recuerda, la búsqueda binaria opera dividiendo efectivamente el problema a la mitad con cada paso.

Solución:

def binary_search(list, x):
    low = 0
    high = len(list) - 1

    while low <= high:
        mid = (high + low) // 2

        if list[mid] < x:
            low = mid + 1
        elif list[mid] > x:
            high = mid - 1
        else:
            return mid
    return -1

Problema 2: Cambio de Monedas (Algoritmo Voraz)

Dada una lista de denominaciones de monedas y un valor n, escribe una función que calcule el número mínimo de monedas necesarias para hacer cambio por n. Utiliza un algoritmo voraz que siempre selecciona la denominación más grande menor o igual al monto restante a cambiar. Prueba tu función con varios conjuntos de monedas, como las denominaciones estándar de EE. UU. o euros.

Solución:

def coin_change(coins, n):
    coins.sort(reverse=True)
    count = 0
    for coin in coins:
        while n >= coin:
            n -= coin
            count += 1
        if n == 0:
            return count
    return count

Problema 3: Serie Fibonacci (Programación Dinámica)

Escribe una función para calcular el enésimo número de Fibonacci. La serie de Fibonacci se define como: F(0) = 0, F(1) = 1, y F(n) = F(n-1) + F(n-2) para n > 1. Primero, implementa esto usando recursión simple, luego optimiza tu función usando programación dinámica para almacenar y reutilizar valores calculados.

Solución:

def fibonacci(n, computed = {0: 0, 1: 1}):
    if n not in computed:
        computed[n] = fibonacci(n - 1, computed) + fibonacci(n - 2, computed)
    return computed[n]

Problema 4: Suma de Números Naturales (Algoritmo Recursivo)

Escribe una función que calcule la suma de todos los números naturales desde 1 hasta n usando un algoritmo recursivo. Compara la solución recursiva con una solución iterativa y discute las diferencias.

Solución:

def recursive_sum(n):
    if n <= 1:
        return n
    else:
        return n + recursive_sum(n - 1)

def iterative_sum(n):
    return n * (n + 1) // 2

Problema 5: QuickSort (Divide y Conquista)

Implementa el algoritmo QuickSort que ordena una matriz de enteros. QuickSort es un algoritmo de Divide y Conquista. Elige un elemento como pivote y particiona la matriz dada alrededor del pivote seleccionado.

Solución:

def quicksort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quicksort(left) + middle + quicksort(right)

Problema 6: Implementación de una Pila usando Recursión (Algoritmo Recursivo)

Implementa una estructura de datos de pila utilizando recursión. Tu pila debería tener funciones pushpop, y peek.

Solución:

class Stack:
    def __init__(self):
        self.stack = []

    def push(self, item):
        self.stack.append(item)

    def pop(self):
        if len(self.stack) < 1:
            return None
        return self.stack.pop()

    def peek(self):
        if self.stack:
            return self.stack[-1]
        return None

Recuerda, el objetivo de estos problemas prácticos es obtener una comprensión práctica de los diferentes tipos de algoritmos, cómo funcionan y dónde se pueden aplicar. Intenta resolver todos los problemas y compara las soluciones para ver la diferencia entre estos tipos de algoritmos. ¡Buena suerte!

En el próximo capítulo, exploraremos tipos de algoritmos más avanzados y sus aplicaciones en la resolución de problemas del mundo real. ¡Mantente atento!

4.5 Problemas de práctica

Problema 1: Búsqueda Binaria (Divide y Conquista)

Dada una lista ordenada de n enteros y un entero objetivo x, escribe una función que encuentre la posición de x en la lista usando un algoritmo de búsqueda binaria. Recuerda, la búsqueda binaria opera dividiendo efectivamente el problema a la mitad con cada paso.

Solución:

def binary_search(list, x):
    low = 0
    high = len(list) - 1

    while low <= high:
        mid = (high + low) // 2

        if list[mid] < x:
            low = mid + 1
        elif list[mid] > x:
            high = mid - 1
        else:
            return mid
    return -1

Problema 2: Cambio de Monedas (Algoritmo Voraz)

Dada una lista de denominaciones de monedas y un valor n, escribe una función que calcule el número mínimo de monedas necesarias para hacer cambio por n. Utiliza un algoritmo voraz que siempre selecciona la denominación más grande menor o igual al monto restante a cambiar. Prueba tu función con varios conjuntos de monedas, como las denominaciones estándar de EE. UU. o euros.

Solución:

def coin_change(coins, n):
    coins.sort(reverse=True)
    count = 0
    for coin in coins:
        while n >= coin:
            n -= coin
            count += 1
        if n == 0:
            return count
    return count

Problema 3: Serie Fibonacci (Programación Dinámica)

Escribe una función para calcular el enésimo número de Fibonacci. La serie de Fibonacci se define como: F(0) = 0, F(1) = 1, y F(n) = F(n-1) + F(n-2) para n > 1. Primero, implementa esto usando recursión simple, luego optimiza tu función usando programación dinámica para almacenar y reutilizar valores calculados.

Solución:

def fibonacci(n, computed = {0: 0, 1: 1}):
    if n not in computed:
        computed[n] = fibonacci(n - 1, computed) + fibonacci(n - 2, computed)
    return computed[n]

Problema 4: Suma de Números Naturales (Algoritmo Recursivo)

Escribe una función que calcule la suma de todos los números naturales desde 1 hasta n usando un algoritmo recursivo. Compara la solución recursiva con una solución iterativa y discute las diferencias.

Solución:

def recursive_sum(n):
    if n <= 1:
        return n
    else:
        return n + recursive_sum(n - 1)

def iterative_sum(n):
    return n * (n + 1) // 2

Problema 5: QuickSort (Divide y Conquista)

Implementa el algoritmo QuickSort que ordena una matriz de enteros. QuickSort es un algoritmo de Divide y Conquista. Elige un elemento como pivote y particiona la matriz dada alrededor del pivote seleccionado.

Solución:

def quicksort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quicksort(left) + middle + quicksort(right)

Problema 6: Implementación de una Pila usando Recursión (Algoritmo Recursivo)

Implementa una estructura de datos de pila utilizando recursión. Tu pila debería tener funciones pushpop, y peek.

Solución:

class Stack:
    def __init__(self):
        self.stack = []

    def push(self, item):
        self.stack.append(item)

    def pop(self):
        if len(self.stack) < 1:
            return None
        return self.stack.pop()

    def peek(self):
        if self.stack:
            return self.stack[-1]
        return None

Recuerda, el objetivo de estos problemas prácticos es obtener una comprensión práctica de los diferentes tipos de algoritmos, cómo funcionan y dónde se pueden aplicar. Intenta resolver todos los problemas y compara las soluciones para ver la diferencia entre estos tipos de algoritmos. ¡Buena suerte!

En el próximo capítulo, exploraremos tipos de algoritmos más avanzados y sus aplicaciones en la resolución de problemas del mundo real. ¡Mantente atento!