Resolução de Problemas de Arrays em Java: Guia de Algoritmos Otimizados

Soma Máxima de Subarray (Questão 53)

O desafio consiste em encontrar a maior soma possível entre todos os subarrays contínuos de um array de inteiros. O foco aqui é garantir eficiência em termos de tempo, percorrendo o array apenas uma vez.

class Solution {
    public int maxSubArray(int[] elementos) {
        int somaGlobal = elementos[0];
        int somaLocal = 0;
        
        for (int item : elementos) {
            somaLocal += item;
            
            // Atualiza o máximo global antes de resetar o acumulador 
            // para lidar corretamente com arrays compostos apenas por números negativos.
            if (somaLocal > somaGlobal) {
                somaGlobal = somaLocal;
            }
            
            if (somaLocal < 0) {
                somaLocal = 0;
            }
        }
        return somaGlobal;
    }
}

Lógica Aplicada: Utilizamos uma variação do algoritmo de Kadane. A estratégia principal é descartar somas acumuladas que se tornam negativas, pois elas reduziriam o potencial de soma dos elementos subsequentes. A ordem da comparação garante que o maior valor individual seja retornado mesmo que todos os números sejam negativos.

Mesclagem de Intervalos (Questão 56)

Dada uma coleção de intervalos, o objetivo é combinar aqueles que se sobrepõem em um único intervalo contínuo.

class Solution {
    public int[][] merge(int[][] intervalos) {
        if (intervalos.length <= 1) return intervalos;

        // Ordenação baseada no ponto inicial de cada intervalo
        Arrays.sort(intervalos, (a, b) -> Integer.compare(a[0], b[0]));

        List<int[]> listaMesclada = new ArrayList<>();
        int[] intervaloAtual = intervalos[0];
        listaMesclada.add(intervaloAtual);

        for (int[] proximo : intervalos) {
            int fimAtual = intervaloAtual[1];
            int inicioProximo = proximo[0];
            int fimProximo = proximo[1];

            if (inicioProximo <= fimAtual) {
                // Existe sobreposição, expande o fim do intervalo atual
                intervaloAtual[1] = Math.max(fimAtual, fimProximo);
            } else {
                // Sem sobreposição, move para o próximo intervalo
                intervaloAtual = proximo;
                listaMesclada.add(intervaloAtual);
            }
        }

        return listaMesclada.toArray(new int[listaMesclada.size()][]);
    }
}

Lógica Aplicada: O pré-requisito crucial é a ordenação. Uma vez ordenados pelo início, podemos comparar o fim do intervalo atual com o início do próximo. Se houver intersecção, fundimos os dois mantendo o maior valor de término.

Rotação de Array (Questão 189)

Este problema solicita o deslocamento dos elementos de um array k posições para a direita.

class Solution {
    public void rotate(int[] dados, int k) {
        int n = dados.length;
        k = k % n; // Ajuste para rotações maiores que o tamanho do array
        
        int[] espelho = new int[n];
        for (int i = 0; i < n; i++) {
            int novaPosicao = (i + k) % n;
            espelho[novaPosicao] = dados[i];
        }
        
        System.arraycopy(espelho, 0, dados, 0, n);
    }
}

Lógica Aplicada: Utilizamos o operador de módulo para mapear os novos índices. A criação de um array auxiliar facilita a transferência direta, evitando a perda de dados durante deslocamentos sequenciais complexos.

Produto do Array Exceto o Próprio Elemento (Questão 238)

O requisito é gerar um novo array onde cada posição i contenha o produto de todos os números do array original, exceto o valor presente na posição i, sem utilizar a operação de divisão.

class Solution {
    public int[] productExceptSelf(int[] entrada) {
        int tamanho = entrada.length;
        int[] resultado = new int[tamanho];
        
        // Passo 1: Calcular produtos à esquerda
        resultado[0] = 1;
        for (int i = 1; i < tamanho; i++) {
            resultado[i] = resultado[i - 1] * entrada[i - 1];
        }
        
        // Passo 2: Calcular produtos à direita e multiplicar pelo resultado atual
        int fatorDireita = 1;
        for (int i = tamanho - 1; i >= 0; i--) {
            resultado[i] = resultado[i] * fatorDireita;
            fatorDireita *= entrada[i];
        }
        
        return resultado;
    }
}

Lógica Aplicada: Dividimos o problema em duas passagesn. Na primeira, armazenamos o produto acumulado de todos os itens à esquerda de cada índice. Na segunda, percorermos de trás para frente multiplicando pelo produto acumulado à direita, otimizando o espaço para O(1) adicional além do array de saída.

Primeiro Inteiro Positivo Ausente (Questão 41)

O objetivo é encontrar o menor número inteiro positivo (maior que zero) que não está presente em um array não ordenado, respeitando o tempo O(n) e espaço constante.

class Solution {
    public int firstMissingPositive(int[] valores) {
        int n = valores.length;

        // Normalização: substituir valores irrelevantes
        for (int i = 0; i < n; i++) {
            if (valores[i] <= 0 || valores[i] > n) {
                valores[i] = n + 1;
            }
        }

        // Usar o array como uma Hash Map in-place através de sinalização negativa
        for (int i = 0; i < n; i++) {
            int num = Math.abs(valores[i]);
            if (num <= n) {
                int indice = num - 1;
                if (valores[indice] > 0) {
                    valores[indice] = -valores[indice];
                }
            }
        }

        // O primeiro índice com valor positivo indica o número ausente
        for (int i = 0; i < n; i++) {
            if (valores[i] > 0) {
                return i + 1;
            }
        }

        return n + 1;
    }
}

Lógica Aplicada: Como o primeiro positivo ausente deve estar entre 1 e n+1, usamos os próprios índices do array para marcar a presença de números. Convertemos os valores presentes em negativos nos índices correspondentes. O primeiro índice que permanecer positivo revela a ausência.

Tags: java Algoritmos Arrays EstruturasDeDados Otimização

Publicado em 7-15 17:32