常见面试算法题(动态规划-股票问题)

144 阅读1分钟

1. 买卖股票的最佳时机

leetcode-cn.com/problems/be…

class Solution {
    public int maxProfit(int[] prices) {
        int n = prices.length;
        //记录【今天之前买入的最小值】
        //计算【今天之前最小值买入,今天卖出的获利】,也即【今天卖出的最大获利】
        //比较【每天的最大获利】,取最大值即可
        if(n <= 1) return 0;
        int min = prices[0] , max = 0;
        for(int num : prices){
            max = Math.max(max , num - min);
            min = Math.min(min , num);
        }
        return max;
    }
}

2. 买卖股票的最佳时机2-尽可能多的交易

leetcode-cn.com/problems/be…

//每次涨了都卖获取最大利润
class Solution {
    public int maxProfit(int[] prices) {
        int n = prices.length;
        if(n <= 1) return 0;
        int res = 0;
        for(int i = 1 ; i < n ;i++){
            res += Math.max(prices[i] - prices[i-1] , 0);
        }
        return res;
    }
}

3. 买卖股票的最佳时机3-最多两次交易

leetcode-cn.com/problems/be…

class Solution {
    public int maxProfit(int[] prices) {
        int n = prices.length;
        if(n < 2) return 0;
        //第一个是天数,第二个是已经买进股票的次数,第三个是当前的持有状态
        //表示第n天,可以买卖股票两次 , 2表示当前是否持有股票 1表示有 0 表示没有
        int[][][] dp = new int[n][3][2];
        for(int i = 0 ; i < n ; i++){
            for(int j = 0 ;j <= 2;j++){
                //基本情况
                if(i == 0){
                    dp[i][j][0] = 0;
                    dp[i][j][1] = -prices[0];
                    continue;
                }
                if(j == 0){
                    dp[i][j][1] = Integer.MIN_VALUE; //表示不可能
                    dp[i][j][0] = 0;
                    continue; 
                }

                dp[i][j][1] = Math.max(dp[i-1][j][1] , dp[i-1][j-1][0]-prices[i]);
                dp[i][j][0] = Math.max(dp[i-1][j][0] , dp[i-1][j][1]+prices[i]);
            }
        }
        return dp[n-1][2][0];
    }
}

4. 买卖股票的最佳时机4-最多k次交易

leetcode-cn.com/problems/be…

class Solution {
    public int maxProfit(int k, int[] prices) {
        int n = prices.length;
        if(n < 2) return 0;
        //和无限次交易一样
        if(k > n/2){

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

        int[][][] dp = new int[n][k+1][2];
        for(int i = 0 ; i < n ; i++){
            for(int j = 0 ; j <= k ; j++){
                if(i == 0){
                    dp[i][j][0] = 0;
                    dp[i][j][1] = -prices[0];
                    continue;
                }
                if(j == 0){
                    dp[i][j][0] = 0;
                    dp[i][j][1] = Integer.MIN_VALUE;
                    continue;
                }
                dp[i][j][1] = Math.max(dp[i-1][j][1] , dp[i-1][j-1][0]-prices[i]);
                dp[i][j][0] = Math.max(dp[i-1][j][0] , dp[i-1][j][1] + prices[i]);
            }
        }
        return dp[n-1][k][0];
    }
}

5. 买卖股票的最佳时机5-含有冷冻期

leetcode-cn.com/problems/be…


class Solution {
    public int maxProfit(int[] prices) {
        int n = prices.length;
        if (n < 1) return 0;
        int[][] dp = new int[n][2];
        for (int i = 0; i < n; i++) {
            if (i == 0){
                dp[0][0] = 0;
                dp[0][1] = -prices[0];
                continue;
            }
            if (i == 1){ //因为第2天也是特殊情况 ,所以初始化一下
                dp[1][0] = Math.max(0 , prices[1] - prices[0]);
                dp[1][1] = Math.max(-prices[0] , -prices[1]);
                continue;
            }
            
            dp[i][0] = Math.max(dp[i-1][0] , dp[i-1][1] + prices[i]);
            dp[i][1] = Math.max(dp[i-1][1] , dp[i-2][0] - prices[i]);
        }
        return dp[n-1][0];
    }
}

6. 买卖股票的最佳时机6-含有手续费

leetcode-cn.com/problems/be…


class Solution {
    public int maxProfit(int[] prices, int fee) {
        int n = prices.length;
        if (n < 1) return 0;
        int[][] dp = new int[n][2];
        for (int i = 0; i < n; i++) {
            if (i == 0){
                dp[0][0] = 0;
                dp[0][1] = -prices[i] - fee;
                continue;
            }
            
            dp[i][0] = Math.max(dp[i-1][0] , dp[i-1][1] + prices[i] );
            dp[i][1] = Math.max(dp[i-1][1] , dp[i-1][0] - prices[i] - fee );
        }
        return dp[n-1][0];
    }
}