Problemas de Compra e Venda de Ações 121, 122 e 123

121. Melhor Momento para Comprar e Vender Ações

Existem três abordagens comuns para resolver este problema:

  • Abordagem Gulosa: Manter o menor valor de compra até o dia atual.
  • Programação Dinâmica 2D: Utilizar uma matriz para representar estados.
  • Prograamção Dinâmica Otimizada: Reduzir para variáveis constantes.
class Solution {
    public int maxProfit(int[] prices) {
        // Abordagem gulosa:
        int menorPreco = prices[0];
        int lucroMaximo = 0;

        for (int preco : prices) {
            menorPreco = Math.min(menorPreco, preco);
            lucroMaximo = Math.max(lucroMaximo, preco - menorPreco);
        }

        return lucroMaximo;
    }
}

class Solution {
    public int maxProfit(int[] prices) {
        int n = prices.length;
        // dp[dia][0] = lucro máximo sem ação no final do dia
        // dp[dia][1] = lucro máximo com ação no final do dia
        int[][] dp = new int[n][2];
        dp[0][0] = 0;
        dp[0][1] = -prices[0];

        for (int i = 1; i < n; i++) {
            dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i]);
            dp[i][1] = Math.max(dp[i-1][1], -prices[i]);
        }

        return dp[n-1][0];
    }
}

class Solution {
    public int maxProfit(int[] prices) {
        int semAcao = 0;
        int comAcao = Integer.MIN_VALUE;

        for (int preco : prices) {
            int novoSemAcao = Math.max(semAcao, comAcao + preco);
            int novoComAcao = Math.max(comAcao, -preco);
            semAcao = novoSemAcao;
            comAcao = novoComAcao;
        }

        return semAcao;
    }
}

122. Melhor Momento para Comprar e Vender Ações II

Diferente do problema anterior, aqui é permitido realizar múltiplas transações. A principal diferença na transição de estado é que, ao comprar uma ação, o lucro considera o estado anterior sem ação (que já pode incluir lucros de transações passadas).

class Solution {
    public int maxProfit(int[] prices) {
        int semAcao = 0;
        int comAcao = Integer.MIN_VALUE;

        for (int preco : prices) {
            int novoSemAcao = Math.max(semAcao, comAcao + preco);
            int novoComAcao = Math.max(comAcao, semAcao - preco);
            semAcao = novoSemAcao;
            comAcao = novoComAcao;
        }

        return semAcao;
    }
}

123. Melhor Momento para Comprar e Vender Ações III

Duas abordagens são possíveis:

  • Abordagem Geral com k=2: Adicionar dimensão para o número de transações.
  • Abordagem com Estados Explícitos: Definir quatro estados para duas transações.
class Solution {
    public int maxProfit(int[] prices) {
        int n = prices.length;
        // dp[dia][k][0] = lucro sem ação, com até k transações
        // dp[dia][k][1] = lucro com ação, com até k transações
        int[][][] dp = new int[n][3][2];

        for (int k = 1; k <= 2; k++) {
            dp[0][k][0] = 0;
            dp[0][k][1] = -prices[0];
        }

        for (int i = 1; i < n; i++) {
            for (int k = 1; k <= 2; k++) {
                dp[i][k][0] = Math.max(dp[i-1][k][0], dp[i-1][k][1] + prices[i]);
                dp[i][k][1] = Math.max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i]);
            }
        }

        return dp[n-1][2][0];
    }
}

class Solution {
    public int maxProfit(int[] prices) {
        int primeiraTransacaoSemAcao = 0;
        int primeiraTransacaoComAcao = Integer.MIN_VALUE;
        int segundaTransacaoSemAcao = 0;
        int segundaTransacaoComAcao = Integer.MIN_VALUE;

        for (int preco : prices) {
            segundaTransacaoSemAcao = Math.max(segundaTransacaoSemAcao, segundaTransacaoComAcao + preco);
            segundaTransacaoComAcao = Math.max(segundaTransacaoComAcao, primeiraTransacaoSemAcao - preco);
            primeiraTransacaoSemAcao = Math.max(primeiraTransacaoSemAcao, primeiraTransacaoComAcao + preco);
            primeiraTransacaoComAcao = Math.max(primeiraTransacaoComAcao, -preco);
        }

        return segundaTransacaoSemAcao;
    }
}

Tags: programação dinâmica algoritmo guloso Compra e Venda de Ações LeetCode 121 LeetCode 122

Publicado em 8-4 09:39