Implementaciones en Java de algoritmos para desafíos de LeetCode

Este documento explora soluciones en Java para tres problemas comunes de LeetCode, destacando técnicas algorítmicas esenciales.

Para el problema de encontrar la subcadena palindrómica más larga, se emplea programación dinámica. Se construye una tabla booleana donde las celdas indican si un segmento es palíndromo, partiendo de casos base y apliacndo una ecuación de recurrencia que verifica los caracteres extremos y el interior.


public String findLongestPalindrome(String str) {
    int length = str.length();
    boolean[][] palindromeTable = new boolean[length][length];
    int bestStart = 0, bestLength = 1;
    for (int idx = 0; idx < length; idx++) {
        palindromeTable[idx][idx] = true;
    }
    for (int segLen = 2; segLen <= length; segLen++) {
        for (int startIdx = 0; startIdx <= length - segLen; startIdx++) {
            int endIdx = startIdx + segLen - 1;
            if (segLen == 2) {
                palindromeTable[startIdx][endIdx] = (str.charAt(startIdx) == str.charAt(endIdx));
            } else {
                palindromeTable[startIdx][endIdx] = palindromeTable[startIdx + 1][endIdx - 1] &&
                    (str.charAt(startIdx) == str.charAt(endIdx));
            }
            if (palindromeTable[startIdx][endIdx] && segLen > bestLength) {
                bestLength = segLen;
                bestStart = startIdx;
            }
        }
    }
    return str.substring(bestStart, bestStart + bestLength);
}

En el problema del contenedor con mayor volumen de agua, se utiliza un enfoque de dos punteros. Dos indicadores se colocan en los extremos del areglo de alturas, y se desplazan hacia el centro, moviendo el puntero que apunta a la menor altura, mientras se calcula el área máxima en cada iteración.


public int calculateMaxWaterVolume(int[] heights) {
    int ptrLeft = 0, ptrRight = heights.length - 1;
    int maxVolume = 0;
    while (ptrLeft < ptrRight) {
        int currentWidth = ptrRight - ptrLeft;
        int minHeight = Math.min(heights[ptrLeft], heights[ptrRight]);
        maxVolume = Math.max(maxVolume, currentWidth * minHeight);
        if (heights[ptrLeft] < heights[ptrRight]) {
            ptrLeft++;
        } else {
            ptrRight--;
        }
    }
    return maxVolume;
}

Para la suma de tres números, primero se ordena el areglo y luego se itera sobre cada elemento. Para cada valor, se aplican dos punteros en el subarreglo restante para hallar combinaciones que sumen el objetivo, omitiendo duplicados mediante saltos condicionales en los bucles.


public List<list>> findTripletsWithSumZero(int[] numbers) {
    List<list>> triplets = new ArrayList<>();
    Arrays.sort(numbers);
    for (int i = 0; i < numbers.length - 2; i++) {
        if (i > 0 && numbers[i] == numbers[i - 1]) continue;
        int requiredSum = -numbers[i];
        int leftPtr = i + 1, rightPtr = numbers.length - 1;
        while (leftPtr < rightPtr) {
            int currentSum = numbers[leftPtr] + numbers[rightPtr];
            if (currentSum == requiredSum) {
                triplets.add(Arrays.asList(numbers[i], numbers[leftPtr], numbers[rightPtr]));
                while (leftPtr < rightPtr && numbers[leftPtr] == numbers[leftPtr + 1]) leftPtr++;
                while (leftPtr < rightPtr && numbers[rightPtr] == numbers[rightPtr - 1]) rightPtr--;
                leftPtr++;
                rightPtr--;
            } else if (currentSum < requiredSum) {
                leftPtr++;
            } else {
                rightPtr--;
            }
        }
    }
    return triplets;
}
</list></list>

Etiquetas: java leetcode programación dinámica técnica de dos punteros algoritmos de búsqueda

Publicado el 6-14 23:58