最简单:
122. 买卖股票的最佳时机 II (能够买卖无数次)
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
class Solution { public: int maxProfit(vector<int>& prices) { int n = prices.size(); if (n <= 0) return 0; /*int dp[2][n]; 就买入和卖出两个状态: memset(dp,0,sizeof(dp)); dp[0][0] = -prices[0]; dp[1][0] = 0; for(int i = 1; i < n; i++){ dp[0][i] = max(dp[0][i-1],dp[1][i-1] - prices[i]); dp[1][i] = max(dp[0][i-1] + prices[i],dp[1][i-1]); } return dp[1][n-1]; */
// 空间优化
int hold, sell; hold = -prices[0]; sell = 0; for (int i = 1; i < n; i++){ int temp = hold; hold = max(hold,sell - prices[i]); sell = max(sell,temp + prices[i]); } return sell; } };
121. 买卖股票的最佳时机(能够买卖一次)
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
注意你不能在买入股票前卖出股票。
比之前的多了一种状态:
class Solution { public: int maxProfit(vector<int>& prices) { int n = prices.size(); if(n == 0) return 0; int dp[n][2][2];//多了一个状态,剩余买卖的次数 memset(dp,0xbf,sizeof(dp)); //初始化第1天买入和卖出; dp[0][0][0] = -prices[0]; dp[0][1][1] = 0; for(int i = 1; i < n; i++){ // 买入并且还剩一次是不可能的 dp[i][0][0] = max(dp[i-1][1][1]-prices[i],dp[i-1][0][0]); dp[i][1][0] = max(dp[i-1][0][0]+prices[i],dp[i-1][1][0]); dp[i][1][1] = dp[i-1][1][1]; } return max(dp[n-1][1][0],0); } };
滚动数组优化:
class Solution { public: int maxProfit(vector<int>& prices) { int n = prices.size(); if(n == 0) return 0; int dp[2][2]; memset(dp,0xbf,sizeof(dp)); dp[0][0] = -prices[0]; dp[1][1] = 0; for(int i = 1; i < n;i++){ int temp[2][2]; temp[0][0] = max(dp[0][0],dp[1][1] - prices[i]); temp[1][0] = max(dp[0][0]+prices[i],dp[1][0]); dp[0][0] = temp[0][0]; dp[1][0] = temp[1][0]; } return max(dp[1][0],0); } };
123. 买卖股票的最佳时机 III
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
直接滚动数组优化版本:dp[0][ j ]表示买入状态下还剩 j 次;dp[1][j]表示卖出状态下还剩 j 次;
class Solution { public: int maxProfit(vector<int>& prices) { int n = prices.size(); if(n == 0) return 0; vector<vector<int>> dp(2,vector<int>(3,0xbfbfbfbf)); vector<vector<int>> temp(2,vector<int>(3,0xbfbfbfbf)); dp[0][1] = -prices[0]; dp[1][2] = 0; for(int i = 1; i < n; i++){ temp[0][0] = max(dp[0][0],dp[1][1]-prices[i]); temp[0][1] = max(dp[0][1],dp[1][2]-prices[i]); //temp[0][2]不可能; temp[1][0] = max(dp[1][0],dp[0][0]+prices[i]); temp[1][1] = max(dp[1][1],dp[0][1]+prices[i]); temp[1][2] = dp[1][2]; dp = temp; } return max(dp[1][2],max(dp[1][1],dp[1][0])); } };
188. 买卖股票的最佳时机 IV(基本模板)
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。
注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
class Solution { public: int maxProfit(int k, vector<int>& prices) { //k的大小要分类讨论: int n = prices.size(); if(n == 0 || k == 0) return 0; if(k > n/2){// k > n/2时,相当于可以交易无数次; int sell,hold,temp; sell = 0; hold = -prices[0]; for(int i = 1; i < n; i++){ temp = hold; hold = max(hold,sell-prices[i]); sell = max(sell,temp+prices[i]); } return sell; } vector<vector<int>> dp(2,vector<int>(k+1,0xbfbfbfbf)); vector<vector<int>> temp(2,vector<int>(k+1,0xbfbfbfbf)); dp[0][k-1] = -prices[0]; dp[1][k] = 0; for(int i = 1; i < n; i++){ for(int j = 0; j < k; j++) temp[0][j] = max(dp[0][j],dp[1][j+1]-prices[i]); for(int j = 0; j < k;j++) temp[1][j] = max(dp[1][j],dp[0][j]+prices[i]); temp[1][k] = 0; dp = temp; } return *max_element(dp[1].begin(),dp[1].end()); } };
309. 最佳买卖股票时机含冷冻期
给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
class Solution { public: int maxProfit(vector<int>& prices) { int n = prices.size(); if(n == 0) return 0; // 比最简单的多了一种状态,冷冻状态; //dp[0]代表买入,dp[1]代表卖出,dp[2]代表冷冻 vector<int> dp(3),temp(3); dp[0] = -prices[0]; dp[1] = dp[2] = 0; for(int i = 1; i < n; i++){ temp[0] = max(dp[0],dp[2]-prices[i]); temp[1] = max(dp[1],dp[0]+prices[i]); temp[2] = dp[1]; dp = temp; } return max(dp[1],dp[2]); } };
714. 买卖股票的最佳时机含手续费
给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 ;非负整数 fee 代表了交易股票的手续费用。
你可以无限次地完成交易,但是你每次交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。
返回获得利润的最大值。
就在最简单的基础上,状态转移方程变一下就好了;
class Solution { public: int maxProfit(vector<int>& prices, int fee) { int n = prices.size(); if(n == 0) return 0; int hold, sell,temp; hold = -prices[0]-fee; sell = 0; for(int i = 1; i < n; i++){ temp = hold; hold = max(hold,sell-prices[i]-fee); sell = max(sell,temp+prices[i]); } return sell; } };