Coding Problem 10

Muy buenas a todos y todas, seguimos con nuestros Coding Problems. Es el siguiente:


Dado un array de enteros, devuelve los índices de dos números cuya suma, sea el valor pasado por parámetro.


Tú puedes asumir que cada ejecución solo puede tener 1 solución, y no puedes usar el mismo elemento 2 veces.


Ejemplo:


Dado: nums = [2, 7, 11, 15], objetivo = 9

Devuelve: [0, 1]. Porque nums[0] + nums[1] = 2 +7 = 9


Solución:


Usaremos el ejemplo de arriba para el test principal:


Tests:

public class ProblemTest{

    @Test
    public void shouldReturnEmptyArrayWhenPassEmptyArray() {
        int[] nums = new int[0];

        assertEquals(0, Problem.getIndexesOfSum(nums, 8).length);
    }

    @Test
    public void shouldReturnEmptyArrayWhenPassNull() {
        assertEquals(0, Problem.getIndexesOfSum(null, 8).length);
    }

    @Test
    public void shouldReturnIndexesTheirSumIsTheTarget() {
        int[] nums = new int[]{2, 7, 11, 15};

        assertEquals(0, Problem.getIndexesOfSum(nums, 9)[0]);
        assertEquals(1, Problem.getIndexesOfSum(nums, 9)[1]);
    }
}

Aquí comprobamos que el array que pasamos no pueda ser vacío ni nulo, y además realizamos el test con el ejemplo antes mencionado.


El código mínimo para pasar esto, fue hecho bastante rápido, así que lo refactorizaremos, pero aquí te dejo la primera aproximación.


Código:

public static int[] getIndexesOfSum(final int[] nums, final int target){
    if(nums != null && nums.length > 0){

        for(int i = 0; i < nums.length; i++){
            for(int j = 0; j < nums.length; j++){
                if(j != i && nums[i] + nums[j] == target){
                    return new int[] {i, j};
                }
            }
        }
    }

    return new int[0];
}

Bien, vamos a darlo un toque más limpio y elegante:


Le he dado un poco de semántica, separado en métodos, y además lo he enfocado de otra manera, buscando el complementario al número actual, de esa forma es más intuitivo:

public static int[] getIndexesOfSum(final int[] nums, final int target){
    if(nums != null && nums.length > 0){

        for(int i = 0; i < nums.length; i++){
            int complementaryPosition = containsComplementary(nums, target - nums[i]);
            if(existsComplementary(complementaryPosition)) {
                return new int[]{i, complementaryPosition};
            }
        }
    }

    return new int[0];
}

private static boolean existsComplementary(int complementary) {
    return complementary != -1;
}

private static int containsComplementary(int[] nums, int value) {
    for (int i = 0; i < nums.length; i++) {
        if(nums[i] == value) {
            return i;
        }
    }

    return -1;
}

Si conoces una manera más eficiente, o más sencilla, comentala por Twitter, Linkedin, o déjala en los comentarios :)


Espero que te haya gustado, nos vemos en la próxima.



©2020 por Juanma Perez.