Dos punteros en C: ejercicio resuelto

Dos punteros en C: ejercicio resuelto

Si buscas dos punteros en C ejercicio resuelto, aquí tienes tres aplicaciones clásicas de la técnica: encontrar un par con suma objetivo en un array ordenado, revertir un array in-place y eliminar duplicados de un array ordenado, todos en O(n) y sin memoria adicional.

La técnica de dos punteros consiste en mantener dos índices que avanzan desde los extremos hacia el centro (o ambos hacia la derecha a velocidades distintas) para evitar el doble bucle O(n²).

Enunciado

Dado el array ordenado {1, 2, 3, 4, 6, 8, 11}:

  1. Encuentra todos los pares con suma 10.
  2. Revierte el array in-place.
  3. Dado {1, 1, 2, 2, 3, 4, 4, 5}, elimina los duplicados y devuelve la nueva longitud.

Solución en C

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <stdio.h>

/* 1. Pares con suma objetivo en array ordenado */
void pares_suma(const int arr[], int n, int objetivo) {
    int izq = 0, der = n - 1;
    printf("Pares con suma %d: ", objetivo);
    while (izq < der) {
        int s = arr[izq] + arr[der];
        if (s == objetivo) {
            printf("(%d,%d) ", arr[izq], arr[der]);
            izq++; der--;
        } else if (s < objetivo) {
            izq++;
        } else {
            der--;
        }
    }
    printf("\n");
}

/* 2. Revertir array in-place */
void revertir(int arr[], int n) {
    int izq = 0, der = n - 1;
    while (izq < der) {
        int tmp = arr[izq];
        arr[izq++] = arr[der];
        arr[der--] = tmp;
    }
}

/* 3. Eliminar duplicados (array ordenado), devuelve nueva longitud */
int sin_duplicados(int arr[], int n) {
    if (n == 0) return 0;
    int escritura = 0;
    for (int lectura = 1; lectura < n; lectura++) {
        if (arr[lectura] != arr[escritura])
            arr[++escritura] = arr[lectura];
    }
    return escritura + 1;
}

int main(void) {
    int a[] = {1, 2, 3, 4, 6, 8, 11};
    pares_suma(a, 7, 10);

    revertir(a, 7);
    printf("Revertido: ");
    for (int i = 0; i < 7; i++) printf("%d ", a[i]);
    printf("\n");

    int b[] = {1, 1, 2, 2, 3, 4, 4, 5};
    int nueva_len = sin_duplicados(b, 8);
    printf("Sin duplicados (len=%d): ", nueva_len);
    for (int i = 0; i < nueva_len; i++) printf("%d ", b[i]);
    printf("\n");

    return 0;
}

Resultado esperado

1
2
3
Pares con suma 10: (2,8) (4,6) 
Revertido: 11 8 6 4 3 2 1 
Sin duplicados (len=5): 1 2 3 4 5 

Errores frecuentes

  • Aplicar dos punteros sobre un array no ordenado para la búsqueda de par: la técnica solo funciona si el array está ordenado.
  • No actualizar ambos punteros cuando se encuentra el par: quedarse en el mismo índice provoca un bucle infinito.
  • Confundir el puntero de lectura con el de escritura en la eliminación de duplicados: el puntero de escritura avanza solo cuando hay un elemento nuevo.
  • Usar índices con signo cuando el array tiene tamaño 0: der = n - 1 con n = 0 da -1 y el bucle no se ejecuta correctamente en todos los compiladores.

Aplicación práctica

Dos punteros es una técnica fundamental en problemas de arrays y cadenas: suma de tres números, contenedor con más agua, palíndromos y partición de arrays. Aparece con frecuencia en entrevistas técnicas y es la base de algoritmos más complejos como la ventana deslizante.

Siguiente ejercicio recomendado

Práctica guiada y libro completo

Si quieres una ruta completa con progresión real de dificultad:

FAQ

¿Por qué la técnica de dos punteros requiere que el array esté ordenado?

Porque la lógica de avance depende de comparar la suma con el objetivo: si la suma es demasiado pequeña, avanzar el puntero izquierdo aumenta la suma (elementos más grandes hacia la derecha); si es demasiado grande, retroceder el derecho la reduce. Sin orden, no hay garantía de que mover un puntero cambie la suma en la dirección correcta.

¿Cuándo usar dos punteros frente a una tabla hash?

Dos punteros funciona en O(n) con O(1) de espacio extra y requiere el array ordenado. Una tabla hash también da O(n) pero usa O(n) de espacio y no requiere ordenación previa. Se prefiere dos punteros cuando el espacio es limitado o el array ya está ordenado.

¿Se puede aplicar la técnica con más de dos punteros?

Sí. El problema de tres sumas (3-sum) fija un elemento con un bucle exterior y aplica dos punteros en el interior, logrando O(n²) en lugar del O(n³) del enfoque de fuerza bruta.