Loading

买卖股票的最佳时机

买卖股票的最佳时机(动态规划)

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。

注意:你不能在买入股票前卖出股票。

来源:力扣(LeetCode)https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock

/**
【动态规划】
前i天的最大收益 = max{前i-1天的最大收益, 第i天的价格 - 前i-1天中的最低价格}
**/
int maxProfit(vector<int>& prices) {
    int days = prices.size();
    if(days < 2)
        return 0;
    int pre_min = prices[0]; // 前 i-1 天中的最低价格
    int max_earn = 0;        // 前 i-1 天的最大收益
    for(int i = 1; i < days; ++i){
        max_earn = max(max_earn, prices[i] - pre_min);
        pre_min = min(pre_min, prices[i]);
    }

    return max_earn;
}

买卖股票的最佳时机 II(贪心)

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

来源:力扣(LeetCode) https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii

/** 【贪心】
    // 遇到低价(比前后都低)便买入
    // 遇到高价比前后都高)就卖出

    // 持有时间必然是价格上升时间段 才有最大利益
    // \          /
    //  \  /\    /
    //   \/  \  /
    //        \/
**/
    int maxProfit(vector<int>& prices) {
        int sum = 0;
        for(int i = 1; i < prices.size(); ++i){
            if(prices[i] > prices[i-1])
                sum += prices[i] - prices[i-1];
        }
        return sum;
    }

买卖股票的最佳时机 III(动态规划)

给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

来源:力扣(LeetCode)https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii

/**
【动态规划】
第i天结束时的可能状态:
    1、无买卖操作            0
    2、第一次买入            buy_first
    3、第一次买卖交易完成     sell_first
    4、第二次买入            buy_second
    5、第二次交易完成        sell_second
**/

int maxProfit(vector<int>& prices) {
    int days = prices.size();
    if(days <= 1) return 0;

    int buy_first = -prices[0], sell_first = 0;
    int buy_second = -prices[0], sell_second = 0;
    for(int i = 1; i < days; ++i){
        sell_second = max(sell_second, prices[i] + buy_second);
        buy_second = max(buy_second, sell_first - prices[i]);
        sell_first = max(sell_first, buy_first + prices[i]);
        buy_first = max(buy_first, -prices[i]);
    }

    return max(sell_first, sell_second);
}

买卖股票的最佳时机 IV(动态规划)

给定一个整数数组 prices ,它的第 i 个元素 prices[i] 是一支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

来源:力扣(LeetCode)https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv

/**
【动态规划】
第i天结束时的可能状态:
    1、无买卖操作               0
    2、第j次买入股票            buy[j]  0 < j <= k
    3、第j次卖出股票            sell[j]  0 < j <= k
**/
int maxProfit(int k, vector<int>& prices) {
    int days = prices.size();
    if(k < 1 || days <= 1)
        return 0;
    vector<int> buy(k, -prices[0]);  // buy[j] 第j次买入股票后的收益
    vector<int> sell(k, 0);          // sell[j] 第j次卖出股票后的收益
    for(int i = 1; i < days; ++i){
        for(int j = k - 1; j > 0; --j){
            sell[j] = max(sell[j], buy[j] + prices[i]);
            buy[j] = max(buy[j], sell[j-1] - prices[i]);
        }
        sell[0] = max(sell[0], buy[0] + prices[i]);
        buy[0] = max(buy[0], -prices[i]);
    }

    int max_earn = 0;
    for(auto& val : sell){
        if(max_earn < val)
            max_earn = val;
    }

    return max_earn;
}

买卖股票的最佳时机含手续费(动态规划)

给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 ;非负整数 fee 代表了交易股票的手续费用。

你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。

返回获得利润的最大值。

注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。

来源:力扣(LeetCode)https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee

/**
【动态规划】
第i天结束时的可能状态:
    1、持有股票     hold
    2、售出股票     sellout
* 最后一天不持有股票的利润肯定更大
**/
int maxProfit(vector<int>& prices, int fee) {
    int days = prices.size();
    if(days <= 1)
        return 0;
    int hold = -prices[0]; // 持有股票
    int sellout = 0;        // 售出股票 不持有
    for(int i = 1; i < days; ++i){
        int tmp_hold = max(hold, sellout - prices[i]); 
        sellout = max(sellout, hold + prices[i] - fee);
        hold = tmp_hold;
    }
    return sellout; // 最后一天不持有股票利润肯定更大
}

最佳买卖股票时机含冷冻期(动态规划)

给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。

设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):

你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。

来源:力扣(LeetCode)https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown

/**
【动态规划】
第i天结束时的可能状态:
    1、持有股票     hold
    2、售出股票     sell
    3、冷静期       cool
* 最后一天不持有股票的利润肯定更大
**/
int maxProfit(vector<int>& prices) {
    int days = prices.size();
    if(days <= 1)
        return 0;
    int hold = -prices[0];  // 持有
    int sell = 0;           // 售出
    int cool = 0;           // 冷静期
    for(int i = 1; i < days; ++i){
        int tmp_sell = max(sell, hold + prices[i]);
        int tmp_hold = max(hold, cool -prices[i]);
        cool = max(cool, sell);
        sell = tmp_sell;
        hold = tmp_hold;
    }

    return sell;
}
posted @ 2021-01-25 14:50  JakeLin  阅读(90)  评论(0编辑  收藏  举报