买股票(Ⅰ,Ⅱ,Ⅲ,Ⅳ,冷冻期,手续费)

121.买卖股票的最佳时机

class Solution {
    public int maxProfit(int[] prices) {
        //一次遍历
        int minPrice = prices[0];
        int maxProfit = 0;
        for(int i = 1;i < prices.length;i++){
            if(prices[i] < minPrice)
                minPrice = prices[i];
            else{//若没有买,再试试卖
                maxProfit = Math.max(maxProfit, prices[i]-minPrice);
            }
        }
        return maxProfit;

        //动态规划
        // int[] f = new int[prices.length];//f[i]代表第i天的最大收益
        // f[0] = 0;
        // int earn = 0;
        // for(int i = 1;i < prices.length;i++){
        //     f[i] = Math.max(0, prices[i] - prices[i-1] + f[i-1]);
        //     earn = Math.max(earn, f[i]);
        // }
        // return earn;
    }
}

122.买卖股票的最佳时机Ⅱ

1.动态规划

class Solution {
    public int maxProfit(int[] prices) {
        //动态规划 dp[i][1]表示第i天持有股票的收益,dp[i][0]表示第i天未持有股票的收益
        int n = prices.length;
        // int[][] dp = new int[n][2];
        // dp[0][0] = 0;//第一天不买
        // dp[0][1] = -prices[0];//第一天就买
        //空间优化
        int dp0 = 0;
        int dp1 = -prices[0];
        for(int i = 1;i < n;i++){
            int newDp0 = Math.max(dp0, dp1+prices[i]);
            int newDp1 = Math.max(dp0-prices[i], dp1);
            dp0 = newDp0;
            dp1 = newDp1;
        }
        return dp0;
    }
}

2.贪心

class Solution {
    public int maxProfit(int[] prices) {
        //不用想复杂,找出上升的段落即可!!    
        int ans = 0;
        for(int i = 1;i < prices.length;i++){
            ans += Math.max(0, prices[i] - prices[i-1]);
        }
        return ans;
    }
}

123.买卖股票的最佳时机Ⅲ

动态规划!

class Solution {
    public int maxProfit(int[] prices) {
        //动态规划yyds!!
        /*对于每一天都有5种状态:
        1.不做操作(无收益可忽略)
        2.完成第一次买buy1
        3.完成第一次卖sel1
        4.完成第二次买buy2
        4.完成第二次卖sel2
        */
        int n = prices.length;
        // int[][] dp = new int[n][4];
        int buy1 = -prices[0], sel1 = 0;
        int buy2 = -prices[0], sel2 = 0;//这里表示刚开始就只进行一次交易
        for(int i = 1;i < n;i++){
            int newBuy1 = Math.max(buy1, -prices[i]);
            int newSel1 = Math.max(sel1, buy1+prices[i]);
            int newBuy2 = Math.max(buy2, sel1-prices[i]);
            int newSel2 = Math.max(sel2, buy2+prices[i]);
            buy1 = newBuy1;sel1 = newSel1;
            buy2 = newBuy2;sel2 = newSel2;
        }
        return Math.max(sel1, sel2);
    }
}

188.买卖股票的最佳时机Ⅳ

class Solution {
    public int maxProfit(int k, int[] prices) {
        //动态规划
        int n = prices.length, ans = 0;
        if(n == 0) return 0;
        int[][] dp = new int[n][k*2];
        //dp[i][0]代表第i天第一次买入,dp[i][1]代表第1次卖出
        //dp[i][2*j]代表第i天第(j+1)次买入,dp[i][2*j+1]代表第i天第(j+1)次卖出
        for(int j = 0;j < k;j++){
            dp[0][2*j] = -prices[0];
            dp[0][2*j+1] = 0;
        }
        for(int i = 1;i < n;i++){
            for(int j = 0;j < k;j++){
                if(j == 0){//第一次买/卖
                    dp[i][0] = Math.max(dp[i-1][0], -prices[i]);
                    dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]+prices[i]);
                }
                else{
                    dp[i][2*j] = Math.max(dp[i-1][2*j],dp[i-1][2*j-1]-prices[i]);//第j+1次买
                    dp[i][2*j+1] = Math.max(dp[i-1][2*j+1], dp[i-1][2*j]+prices[i]);//第j+1次卖
                }

                if(i == n-1){
                    ans = Math.max(ans, dp[i][2*j+1]);
                }
            }
        }
        return ans;
    }
}

309.买卖股票的最佳时机含冷冻期

class Solution {
    public int maxProfit(int[] prices) {
        //动态规划
        int n = prices.length;
        int[][] dp = new int[n][3];
        /*dp[i][0]表示未持有股票且不处于冷冻期
          dp[i][1]表示持有股票
          dp[i][2]表示未持有股票且处于冷冻期,指的是明天不能买股票!!
        */
        dp[0][0] = 0;
        dp[0][1] = -prices[0];
        dp[0][2] = 0;
        for(int i = 1;i < n;i++){
            //画出状态转移!!!
            dp[i][0] = Math.max(dp[i-1][0], dp[i-1][2]);
            dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]-prices[i]);
            dp[i][2] = dp[i-1][1] + prices[i]; 
        }
        return Math.max(dp[n-1][0], dp[n-1][2]);
    }
}

714.买卖股票的最佳时机含手续费

1.动态规划

class Solution {
    public int maxProfit(int[] prices, int fee) {
        //动态规划
        int n = prices.length;
        int[][] dp = new int[n][2];
        dp[0][0] = 0;
        dp[0][1] = -prices[0]-fee;
        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], dp[i-1][0]-prices[i]-fee);
        }
        return dp[n-1][0];
    }
}

2.贪心

class Solution {
    public int maxProfit(int[] prices, int fee) {
        //贪心
        //思想:当我们卖出一支股票时,我们就立即获得了以相同价格并且免除手续费买入一支股票的权利
        int n = prices.length;
        int buy = prices[0] + fee, ans = 0;//假设刚开始就买
        for(int i = 1;i < n;i++){
            if(prices[i] + fee < buy){//若出现更低价,则重新买
                buy = prices[i] + fee;
            }
            else if(prices[i] > buy){//若出现高价则假设卖
                ans += prices[i] - buy;
                buy = prices[i];//以便反悔
            }
        }
        return ans;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值