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];
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章