leetcode——第122题——可以买卖多次股票

题目:
给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格。

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

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

class Solution {
// 贪心算法::其实就是求相邻两天的利润,然后只取正数,也就是局部最优
// 因为连续几天的利润也是相邻两天的利润的总合嘛~~
// 如第0天买入,第3天卖出,那么利润为 prices[3] - prices[0],
// 也就是把利润划分为每天为单位的维度,而不是整体考虑
// prices[3] - prices[0] = (prices[3] - prices[2]) + 
//                         (prices[2] - prices[1]) + 
//                         (prices[1] - prices[0])
public:
    // int maxProfit(vector<int>& prices) 
    // {
    //     int result = 0;
    //     for(int i = 1; i < prices.size(); i++)
    //     {
    //         if((prices[i] - prices[i-1]) > 0)
    //         {
    //             result += prices[i] - prices[i-1];
    //         }
    //     }
    //     return result;
    // }

    // 法二::动态规划
    // 这题就是可以买卖多次
    /*
    时间复杂度:O(n)
    空间复杂度:O(n)
    */
    // 写法一:正常的 dp 数组
    // int maxProfit(vector<int>& prices) 
    // {
    //     // dp[i][0]    第i天 持有股票 的最多现金
    //     // dp[i][1]    第i天 不持有股票 的最多现金
    //     int n = prices.size();
    //     vector<vector<int>> dp(n, vector<int>(2, 0));
    //     dp[0][0] = - prices[0];   // 持股票
    //     for(int i = 1; i < n; i++)
    //     {
    //         // 只有 dp[i][0] 与只能买一次的逻辑不一样,就是当持有股票,且前一天不持有,今天买入的话
    //         // 由 dp[i - 1][1] - prices[i] 得出结果。
    //         dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
    //         dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
    //     }
    //     return max(dp[n - 1][0], dp[n - 1][1]);
    // }

    // 写法二:滚动数组写法
    /*
    时间复杂度:O(n)
    空间复杂度:O(1)
    */
    int maxProfit(vector<int>& prices) 
    {
        int len = prices.size();
        // 滚动数组,为什么设置为 两行呢?
        // 因为只需要保留前一天的状态即可,也就是一共就两天的状态,来回滚动嘛
        vector<vector<int>> dp(2, vector<int>(2, 0));
        dp[0][0] = -prices[0];

        for(int i = 1; i < len; ++i)
        {
            dp[i % 2][0] = max(dp[(i - 1) % 2][0], dp[(i - 1) % 2][1] - prices[i]);
            dp[i % 2][1] = max(dp[(i - 1) % 2][1], dp[(i - 1) % 2][0] + prices[i]);
        }
        return dp[(len - 1) % 2][1];
    }    
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值