
























Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Prepara tus exámenes
Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Prepara tus exámenes con los documentos que comparten otros estudiantes como tú en Docsity
Encuentra los documentos específicos para los exámenes de tu universidad
Estudia con lecciones y exámenes resueltos basados en los programas académicos de las mejores universidades
Responde a preguntas de exámenes reales y pon a prueba tu preparación
Consigue puntos base para descargar
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Comunidad
Pide ayuda a la comunidad y resuelve tus dudas de estudio
Ebooks gratuitos
Descarga nuestras guías gratuitas sobre técnicas de estudio, métodos para controlar la ansiedad y consejos para la tesis preparadas por los tutores de Docsity
Este documento es un conjunto de ejercicios y soluciones de programación en Python, enfocado en estructuras de datos básicas, creado por la Universidad de Atacama. Incluye 60 problemas divididos en tres categorías: arreglos (vectores y matrices), cadenas de caracteres y estructuras de datos avanzadas (como listas enlazadas, árboles, grafos, etc.). Cada ejercicio presenta una descripción clara del problema, seguido de su solución en código Python, con explicaciones de complejidad algorítmica cuando es relevante. Las soluciones abordan desde operaciones básicas hasta algoritmos complejos como Dijkstra, Huffman o árboles B. El documento está organizado de manera pedagógica, con ejemplos prácticos y código bien estructurado, ideal para estudiantes que buscan practicar y entender estructuras de datos en Python.
Tipo: Exámenes
1 / 32
Esta página no es visible en la vista previa
¡No te pierdas las partes importantes!

























Ejercicios de Cadenas de caracteres (strings)
14 num += 1 15 derecha -= 1 16 17 if arriba <= abajo : 18 for i in range ( derecha , izquierda -1 , -1) : 19 matriz [ abajo ][ i ] = num 20 num += 1 21 abajo -= 1 22 23 if izquierda <= derecha : 24 for i in range ( abajo , arriba -1 , -1) : 25 matriz [ i ][ izquierda ] = num 26 num += 1 27 izquierda += 1 28 29 return matriz
1 def encontrar_pico ( nums ) : 2 izquierda , derecha = 0 , len ( nums ) - 3 4 while izquierda < derecha : 5 medio = ( izquierda + derecha ) // 2 6 if nums [ medio ] < nums [ medio +1]: 7 izquierda = medio + 1 8 else : 9 derecha = medio 10 11 return izquierda
1 def interseccion ( nums1 , nums2 ) : 2 set1 = set ( nums1 ) 3 set2 = set ( nums2 ) 4 return list ( set1 & set2 )
1 def max_rectangulo_histograma ( alturas ) : 2 pila = [] 3 max_area = 0 4 alturas. append (0) 5 6 for i , h in enumerate ( alturas ) : 7 while pila and alturas [ pila [ -1]] > h : 8 altura = alturas [ pila. pop () ] 9 ancho = i if not pila else i - pila [ -1] - 1 10 max_area = max ( max_area , altura * ancho ) 11 pila. append ( i ) 12 13 return max_area
1 def max_subarray ( nums ) : 2 max_actual = max_global = nums [0] 3 4 for num in nums [1:]: 5 max_actual = max ( num , max_actual + num )
6 max_global = max ( max_global , max_actual ) 7 8 return max_global
1 def orden_diagonal ( matriz ) : 2 if not matriz : 3 return [] 4 5 filas , cols = len ( matriz ) , len ( matriz [0]) 6 resultado = [] 7 8 for d in range ( filas + cols - 1) : 9 temp = [] 10 i = 0 if d < cols else d - cols + 1 11 j = d if d < cols else cols - 1 12 13 while i < filas and j >= 0: 14 temp. append ( matriz [ i ][ j ]) 15 i += 1 16 j -= 1 17 18 resultado. extend ( temp ) 19 20 return resultado
1 def contar_inversiones ( nums ) : 2 def merge_sort ( nums ) : 3 if len ( nums ) <= 1: 4 return nums , 0 5 6 medio = len ( nums ) // 2 7 izquierda , inv_izq = merge_sort ( nums [: medio ]) 8 derecha , inv_der = merge_sort ( nums [ medio :]) 9 merged , inv_merge = merge ( izquierda , derecha ) 10 11 return merged , inv_izq + inv_der + inv_merge 12 13 def merge ( izquierda , derecha ) : 14 resultado = [] 15 i = j = inv = 0 16 17 while i < len ( izquierda ) and j < len ( derecha ) : 18 if izquierda [ i ] <= derecha [ j ]: 19 resultado. append ( izquierda [ i ]) 20 i += 1 21 else : 22 resultado. append ( derecha [ j ]) 23 j += 1 24 inv += len ( izquierda ) - i 25 26 resultado. extend ( izquierda [ i :]) 27 resultado. extend ( derecha [ j :]) 28 29 return resultado , inv 30 31 _ , total = merge_sort ( nums ) 32 return total
3 return 0 4 5 filas , cols = len ( obstaculos ) , len ( obstaculos [0]) 6 dp = [[0]* cols for _ in range ( filas ) ] 7 dp [0][0] = 1 8 9 for i in range (1 , filas ) : 10 dp [ i ][0] = dp [i -1][0] if obstaculos [ i ][0] == 0 else 0 11 12 for j in range (1 , cols ) : 13 dp [0][ j ] = dp [0][ j -1] if obstaculos [0][ j ] == 0 else 0 14 15 for i in range (1 , filas ) : 16 for j in range (1 , cols ) : 17 if obstaculos [ i ][ j ] == 0: 18 dp [ i ][ j ] = dp [i -1][ j ] + dp [ i ][ j -1] 19 else : 20 dp [ i ][ j ] = 0 21 22 return dp [ -1][ -1]
1 def indice_pivote ( nums ) : 2 suma_total = sum ( nums ) 3 suma_izquierda = 0 4 5 for i , num in enumerate ( nums ) : 6 if suma_izquierda == ( suma_total - suma_izquierda - num ) : 7 return i 8 suma_izquierda += num 9 10 return -
1 def matriz_sumas_acumuladas ( matriz ) : 2 if not matriz : 3 return [] 4 5 filas , cols = len ( matriz ) , len ( matriz [0]) 6 dp = [[0]*( cols +1) for _ in range ( filas +1) ] 7 8 for i in range (1 , filas +1) : 9 for j in range (1 , cols +1) : 10 dp [ i ][ j ] = matriz [i -1][ j -1] + dp [i -1][ j ] + dp [ i ][ j -1] - dp [i -1][ j -1] 11 12 return dp
1 def puede_llegar_final ( nums ) : 2 max_alcanzable = 0 3 for i , num in enumerate ( nums ) : 4 if i > max_alcanzable : 5 return False 6 max_alcanzable = max ( max_alcanzable , i + num ) 7 if max_alcanzable >= len ( nums ) - 1: 8 return True 9 return True
1 def setear_ceros ( matriz ) : 2 filas_cero = set () 3 cols_cero = set () 4 filas = len ( matriz ) 5 cols = len ( matriz [0]) if filas > 0 else 0 6 7 for i in range ( filas ) : 8 for j in range ( cols ) : 9 if matriz [ i ][ j ] == 0: 10 filas_cero. add ( i ) 11 cols_cero. add ( j ) 12 13 for i in range ( filas ) : 14 for j in range ( cols ) : 15 if i in filas_cero or j in cols_cero : 16 matriz [ i ][ j ] = 0 17 18 return matriz
1 def encontrar_duplicados ( nums ) : 2 resultado = [] 3 for num in nums : 4 idx = abs ( num ) - 1 5 if nums [ idx ] < 0: 6 resultado. append ( abs ( num ) ) 7 else : 8 nums [ idx ] *= - 9 return resultado
1 def multiplicar_matrices (A , B ) : 2 filas_A = len ( A ) 3 cols_A = len ( A [0]) if filas_A > 0 else 0 4 filas_B = len ( B ) 5 cols_B = len ( B [0]) if filas_B > 0 else 0 6 7 if cols_A != filas_B : 8 raise ValueError ( " Dimensiones incompatibles para m u l t i p l i c a c i n " ) 9 10 resultado = [[0]* cols_B for _ in range ( filas_A ) ] 11 12 for i in range ( filas_A ) : 13 for j in range ( cols_B ) : 14 for k in range ( cols_A ) : 15 resultado [ i ][ j ] += A [ i ][ k ] * B [ k ][ j ] 16 17 return resultado
Soluciones a los ejercicios de Cadenas
1 def longest_palindrome ( s ) : 2 if not s : 3 return " " 4 5 start , end = 0 , 0 6 for i in range ( len ( s ) ) : 7 len1 = expand_around_center (s , i , i )
7 m [ x ][ y ] = m [ x - 1][ y - 1] + 1 8 if m [ x ][ y ] > longest : 9 longest = m [ x ][ y ] 10 x_longest = x 11 else : 12 m [ x ][ y ] = 0 13 return s1 [ x_longest - longest : x_longest ]
1 def is_valid_parentheses ( s ) : 2 stack = [] 3 mapping = { ’) ’: ’( ’ , ’] ’: ’[ ’ , ’} ’: ’{ ’} 4 for char in s : 5 if char in mapping. values () : 6 stack. append ( char ) 7 elif char in mapping. keys () : 8 if not stack or mapping [ char ] != stack. pop () : 9 return False 10 return not stack
1 def compress_string ( s ) : 2 compressed = [] 3 count = 1 4 for i in range (1 , len ( s ) ) : 5 if s [ i ] == s [i -1]: 6 count += 1 7 else : 8 compressed. append ( s [i -1] + str ( count ) ) 9 count = 1 10 compressed. append ( s [ -1] + str ( count ) ) 11 compressed_str = ’ ’. join ( compressed ) 12 return compressed_str if len ( compressed_str ) < len ( s ) else s
1 def to_title_case ( s ) : 2 return ’ ’. join ( word. capitalize () for word in s. split () )
1 def rotate_string (s , k ) : 2 k = k % len ( s ) if len ( s ) > 0 else 0 3 return s [ - k :] + s [: - k ]
1 def edit_distance ( s1 , s2 ) : 2 m , n = len ( s1 ) , len ( s2 ) 3 dp = [[0] * ( n + 1) for _ in range ( m + 1) ] 4 5 for i in range ( m + 1) : 6 dp [ i ][0] = i 7 for j in range ( n + 1) : 8 dp [0][ j ] = j 9 10 for i in range (1 , m + 1) : 11 for j in range (1 , n + 1) : 12 if s1 [i -1] == s2 [j -1]: 13 dp [ i ][ j ] = dp [i -1][ j -1] 14 else :
15 dp [ i ][ j ] = 1 + min ( dp [i -1][ j ] , dp [ i ][ j -1] , dp [i -1][ j -1]) 16 17 return dp [ m ][ n ]
1 def is_match ( text , pattern ) : 2 memo = {} 3 4 def dp (i , j ) : 5 if (i , j ) not in memo : 6 if j == len ( pattern ) : 7 ans = i == len ( text ) 8 else : 9 first_match = i < len ( text ) and pattern [ j ] in { text [ i ] , ’. ’} 10 if j +1 < len ( pattern ) and pattern [ j +1] == ’* ’: 11 ans = dp (i , j +2) or ( first_match and dp ( i +1 , j ) ) 12 else : 13 ans = first_match and dp ( i +1 , j +1) 14 memo [i , j ] = ans 15 return memo [i , j ] 16 17 return dp (0 , 0)
1 import heapq 2 from collections import defaultdict 3 4 def huffman_encode ( s ) : 5 freq = defaultdict ( int ) 6 for char in s : 7 freq [ char ] += 1 8 9 heap = [[ weight , [ char , " " ]] for char , weight in freq. items () ] 10 heapq. heapify ( heap ) 11 12 while len ( heap ) > 1: 13 lo = heapq. heappop ( heap ) 14 hi = heapq. heappop ( heap ) 15 for pair in lo [1:]: 16 pair [1] = ’0 ’ + pair [1] 17 for pair in hi [1:]: 18 pair [1] = ’1 ’ + pair [1] 19 heapq. heappush ( heap , [ lo [0] + hi [0]] + lo [1:] + hi [1:]) 20 21 encoding = dict ( heapq. heappop ( heap ) [1:]) 22 encoded_str = ’ ’. join ([ encoding [ char ] for char in s ]) 23 24 return encoded_str , encoding
1 def longest_common_subsequence ( s1 , s2 ) : 2 m , n = len ( s1 ) , len ( s2 ) 3 dp = [[0] * ( n + 1) for _ in range ( m + 1) ] 4 5 for i in range (1 , m + 1) : 6 for j in range (1 , n + 1) : 7 if s1 [i -1] == s2 [j -1]: 8 dp [ i ][ j ] = dp [i -1][ j -1] + 1 9 else : 10 dp [ i ][ j ] = max ( dp [i -1][ j ] , dp [ i ][ j -1])
3 def base64_encode ( s ) : 4 return base64. b64encode ( s. encode () ). decode ()
1 def valid_palindrome ( s ) : 2 def is_palindrome (s , left , right ) : 3 while left < right : 4 if s [ left ] != s [ right ]: 5 return False 6 left += 1 7 right -= 1 8 return True 9 10 left , right = 0 , len ( s ) - 1 11 while left < right : 12 if s [ left ] != s [ right ]: 13 return is_palindrome (s , left +1 , right ) or is_palindrome (s , left , right -1) 14 left += 1 15 right -= 1 16 return True
Soluciones a los ejercicios de Estructuras
1 class Estudiante : 2 def init ( self , nombre , edad ) : 3 self. nombre = nombre 4 self. edad = edad 5 self. calificaciones = [] 6 7 def agregar_calificacion ( self , calif ) : 8 self. calificaciones. append ( calif ) 9 10 def promedio ( self ) : 11 return sum ( self. calificaciones ) / len ( self. calificaciones ) if self. calificaciones else 0 12 13 class SistemaEstudiantes : 14 def init ( self ) : 15 self. estudiantes = [] 16 17 def agregar_estudiante ( self , estudiante ) : 18 self. estudiantes. append ( estudiante ) 19 20 def buscar_por_nombre ( self , nombre ) : 21 return [ e for e in self. estudiantes if e. nombre. lower () == nombre. lower () ] 22 23 def mejores_estudiantes ( self , n =3) : 24 return sorted ( self. estudiantes , key = lambda e : e. promedio () , reverse = True ) [: n ]
1 class Nodo : 2 def init ( self , dato ) : 3 self. dato = dato 4 self. siguiente = None 5
6 class ListaEnlazada : 7 def init ( self ) : 8 self. cabeza = None 9 10 def insertar_inicio ( self , dato ) : 11 nuevo = Nodo ( dato ) 12 nuevo. siguiente = self. cabeza 13 self. cabeza = nuevo 14 15 def insertar_final ( self , dato ) : 16 nuevo = Nodo ( dato ) 17 if not self. cabeza : 18 self. cabeza = nuevo 19 return 20 actual = self. cabeza 21 while actual. siguiente : 22 actual = actual. siguiente 23 actual. siguiente = nuevo 24 25 def eliminar ( self , dato ) : 26 if not self. cabeza : 27 return 28 29 if self. cabeza. dato == dato : 30 self. cabeza = self. cabeza. siguiente 31 return 32 33 actual = self. cabeza 34 while actual. siguiente : 35 if actual. siguiente. dato == dato : 36 actual. siguiente = actual. siguiente. siguiente 37 return 38 actual = actual. siguiente 39 40 def invertir ( self ) : 41 previo = None 42 actual = self. cabeza 43 while actual : 44 siguiente = actual. siguiente 45 actual. siguiente = previo 46 previo = actual 47 actual = siguiente 48 self. cabeza = previo
1 class NodoArbol : 2 def init ( self , clave ) : 3 self. clave = clave 4 self. izquierda = None 5 self. derecha = None 6 7 class ArbolBinario : 8 def init ( self ) : 9 self. raiz = None 10 11 def insertar ( self , clave ) : 12 if not self. raiz : 13 self. raiz = NodoArbol ( clave ) 14 else : 15 self. _insertar ( clave , self. raiz ) 16 17 def _insertar ( self , clave , nodo ) :
16 visitados = set () 17 cola = deque ([ inicio ]) 18 resultado = [] 19 20 while cola : 21 nodo = cola. popleft () 22 if nodo not in visitados : 23 visitados. add ( nodo ) 24 resultado. append ( nodo ) 25 for vecino in self. adyacencia [ nodo ]: 26 if vecino not in visitados : 27 cola. append ( vecino ) 28 return resultado 29 30 def dfs ( self , inicio ) : 31 visitados = set () 32 stack = [ inicio ] 33 resultado = [] 34 35 while stack : 36 nodo = stack. pop () 37 if nodo not in visitados : 38 visitados. add ( nodo ) 39 resultado. append ( nodo ) 40 for vecino in reversed ( self. adyacencia [ nodo ]) : 41 if vecino not in visitados : 42 stack. append ( vecino ) 43 return resultado
1 class NodoHash : 2 def init ( self , clave , valor ) : 3 self. clave = clave 4 self. valor = valor 5 self. siguiente = None 6 7 class HashTable : 8 def init ( self , capacidad =100) : 9 self. capacidad = capacidad 10 self. tabla = [ None ] * capacidad 11 12 def _hash ( self , clave ) : 13 return hash ( clave ) % self. capacidad 14 15 def insertar ( self , clave , valor ) : 16 indice = self. _hash ( clave ) 17 if not self. tabla [ indice ]: 18 self. tabla [ indice ] = NodoHash ( clave , valor ) 19 else : 20 actual = self. tabla [ indice ] 21 while actual. siguiente : 22 if actual. clave == clave : 23 actual. valor = valor 24 return 25 actual = actual. siguiente 26 if actual. clave == clave : 27 actual. valor = valor 28 else : 29 actual. siguiente = NodoHash ( clave , valor ) 30 31 def buscar ( self , clave ) : 32 indice = self. _hash ( clave )
33 actual = self. tabla [ indice ] 34 while actual : 35 if actual. clave == clave : 36 return actual. valor 37 actual = actual. siguiente 38 raise KeyError ( clave ) 39 40 def eliminar ( self , clave ) : 41 indice = self. _hash ( clave ) 42 actual = previo = self. tabla [ indice ] 43 44 if not actual : 45 raise KeyError ( clave ) 46 47 if actual. clave == clave : 48 self. tabla [ indice ] = actual. siguiente 49 return 50 51 while actual : 52 if actual. clave == clave : 53 previo. siguiente = actual. siguiente 54 return 55 previo = actual 56 actual = actual. siguiente 57 raise KeyError ( clave )
1 class PilaConMinimo : 2 def init ( self ) : 3 self. pila = [] 4 self. minimos = [] 5 6 def push ( self , valor ) : 7 self. pila. append ( valor ) 8 if not self. minimos or valor <= self. minimos [ -1]: 9 self. minimos. append ( valor ) 10 11 def pop ( self ) : 12 if not self. pila : 13 raise IndexError ( " Pila v a c a " ) 14 valor = self. pila. pop () 15 if valor == self. minimos [ -1]: 16 self. minimos. pop () 17 return valor 18 19 def top ( self ) : 20 if not self. pila : 21 raise IndexError ( " Pila v a c a " ) 22 return self. pila [ -1] 23 24 def get_min ( self ) : 25 if not self. minimos : 26 raise IndexError ( " Pila v a c a " ) 27 return self. minimos [ -1]
1 class NodoAVL : 2 def init ( self , clave ) : 3 self. clave = clave 4 self. izquierda = None 5 self. derecha = None