leetocde188. 买卖股票的最佳时机 IV

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

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

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

示例 1:

输入: [2,4,1], k = 2
输出: 2
解释: 在第 1(股票价格 = 2) 的时候买入,在第 2(股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2

示例 2:

输入: [3,2,6,5,0,3], k = 2
输出: 7
解释: 在第 2(股票价格 = 2) 的时候买入,在第 3(股票价格 = 6) 的时候卖出, 这笔交易所能获得利润 = 6-2 = 4 。
     随后,在第 5(股票价格 = 0) 的时候买入,在第 6(股票价格 = 3) 的时候卖出, 这笔交易所能获得利润 = 3-0 = 3

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题目分析:

依然是采用经典的股票类问题的套路来解决问题,动态规划

完整代码:

下属代码未能完全通过所有测试用例

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        if(prices.size() == 0)
            return 0;
        cout << INT_MAX;
        int cell[prices.size()][k + 1][2];
        for(int i = 0; i < prices.size(); ++i){
            cell[i][0][0] = 0;            
            for(int j = 1; j <= k; ++j){
                if(i == 0){
                    cell[i][j][0] = 0;
                    cell[i][j][1] = -prices[i];
                }
                else{
                    cell[i][j][0] = max(cell[i - 1][j][0], cell[i - 1][j][1] + prices[i]);
                    cell[i][j][1] = max(cell[i - 1][j][1], cell[i - 1][j - 1][0] - prices[i]);
                }
                cout << cell[i][j][0] << " " << cell[i][j][1]<<endl;
            }
        }
        return cell[prices.size() - 1][k][0];
    }
};

运行结果:

209 / 211 个通过测试用例
状态:执行出错
提交时间:0 分钟之前
执行出错信息:
AddressSanitizer: stack-overflow on address 0x373b06242f28 (pc 0x0000004055d8 bp 0x7ffd79ba6e10 sp 0x373b06242f30 T0)
最后执行的输入:
1000000000
[106,373,495,46,359,919,906,440,783,583,784,73,238,701,972,308,165,774,990,675,737,990,713,157,211,880,961,132,980,136,285,239,628,221,948,939,28,541,414,180,171,640,297,873,59,814,832,611,868,633,101,67,396,264,445,548,257,656,624,71,607,67,836,14,373,205,434,203,661,793,45,623,140,67,177,885,155,764,363,269,599,32,228,111,102,565,918,592,604,244,982,533,781,604,115,429,33,894,778,885,145,888,577,275,644,824,277,302,182,94,479,563,52,771,544,7

说明:这里要注意到当交易次数太大时,也就是大于数组长度的一半(因为买入卖出一组操作需要两天的时间),天数可以当成无穷大来处理,也就是考虑状态时忽略天数

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        if(prices.size() == 0)
            return 0;
        if(k > prices.size() / 2)
            return maxProfit1(prices);
        int cell[prices.size()][k + 1][2];
        for(int i = 0; i < prices.size(); ++i){
            cell[i][0][0] = 0;            
            for(int j = 1; j <= k; ++j){
                if(i == 0){
                    cell[i][j][0] = 0;
                    cell[i][j][1] = -prices[i];
                }
                else{
                    cell[i][j][0] = max(cell[i - 1][j][0], cell[i - 1][j][1] + prices[i]);
                    cell[i][j][1] = max(cell[i - 1][j][1], cell[i - 1][j - 1][0] - prices[i]);
                }
                cout << cell[i][j][0] << " " << cell[i][j][1]<<endl;
            }
        }
        return cell[prices.size() - 1][k][0];
    }
private:
    int maxProfit1(vector<int>& prices){        
        int cell[prices.size()][2];
        for(int i = 0; i < prices.size(); ++i){
            if(i == 0){
                cell[i][0] = 0;
                cell[i][1] = -prices[i];
            }
            else{
                cell[i][0] = max(cell[i - 1][0], cell[i - 1][1] + prices[i]);
                cell[i][1] = max(cell[i - 1][1], cell[i - 1][0] - prices[i]);            
            //cout << cell[i][j][0] << " " << cell[i][j][1]<<endl;
            }
        }
        return cell[prices.size() - 1][0];
    }
};

状态压缩
由于当前的结果只和前一天的结果有关,所以可以将三维数组降维成二维,这里要特别注意,降维时,消去的是第一维(和天数相关的这一维)
注意下数组的初始值的处理

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        if(prices.size() == 0)
            return 0; 
        if(k > prices.size()){
            return maxProfit1(prices);
        }
        int cell[k + 1][2];        
        for(int i = 0; i < prices.size(); ++i){
            cell[0][0] = 0;
            cell[0][1] = INT_MIN;
            for(int j = 1; j <= k; ++j){
                if(i == 0){
                    cell[j][0] = 0;
                    cell[j][1] = -prices[i];
                }
                else{                    
                    cell[j][1] = max(cell[j][1], cell[j - 1][0] - prices[i]);
                    cell[j][0] = max(cell[j][0], cell[j][1] + prices[i]); 
                }
            }
        }
        return cell[k][0];
    }
private:
    int maxProfit1(vector<int>& prices){        
        int cell[2];
        for(int i = 0; i < prices.size(); ++i){
            if(i == 0){
                cell[0] = 0;
                cell[1] = -prices[i];
            }
            else{
                cell[0] = max(cell[0], cell[1] + prices[i]);
                cell[1] = max(cell[1], cell[0] - prices[i]);
            }
        }
        return cell[0];
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章