シリーズ株式取引の概要
インタビューの中でシリーズタイトル株取引は、このシリーズは、いくつかの簡単な要約を行う、非常に古典的な、です。
1.一度だけ許さ取引
仮に株価シーケンス(3, 5, 7, 3, 8, 1)
動的計画。プロセスを通して、行動の3種類が購入/売却/無操作、選択はありません。
\(DP [I] \)意味\(私は\)動作を得ることができ、 "売る"ための利益の最大の日です。もちろん、我々は時間の最小値よりも株式を購入する価格を選択し、この時点の前に、長い時間を一定の時間を販売し、あなたが決めることができます\(DP [I] \)の値を。
だから我々は、価格のシリーズを通過することができcur_min
、常にその時点での現在のポイントの前に記録された最低の価格、在庫ように更新\(DP [I] = MAX(0、価格[i]は-cur \ _minの)\) [i]を、そして最終的にすべてのDPを最大値は、売却が最大の利益を得るために、一度だけです。見つけることができ(DP [i]が\)\変数最大で同時に記録しました。
ので\(DP [i]が\)一度だけ使用するので、店舗に専用のアレイを開放する必要がありません。
class Solution {
public:
int maxProfit(vector<int>& prices) {
// 只允许最多一次交易 求最大收益
// 记录当前最小 cur_min dp[i]表示在第i天卖出的最大收益
if(prices.size()<=1) return 0;
int cur_min = prices[0], res = 0;
for(int i=1; i<prices.size(); i++){
res = max(prices[i]-cur_min, res);// dp[i] = prices[i] - cur_min;
cur_min = min(cur_min, prices[i]);
}
return res;
}
};
2.取引の数を制限することなく
株価のシーケンスと仮定すると(1, 2, 3, 4, 5)
。実際には、これは特殊なケースでは、我々は0日で購入することができ、その後、最後の日に売却しました。このとき、最大の利益は4です。
我々はまた、0日に販売の初日を購入することができます。次の日、購入、売却する最初の日。。。この結果は、最大の利益は4は上記と同じです。
だから、より多くの従来の事情のために、例えば(7, 6, 3, 4, 5)
、我々が購入することができない第一及び第二の日で、現在の数よりも大きい価格を見つけることができません後、ため。売り切れの際は3、4は、その後、別の4、5の売りを買ったときに加えて、あなたが買うことができます。最後に、最大の利益は2です。
class Solution {
public:
int maxProfit(vector<int>& prices) {
// 不限制股票的买卖次数
// 只要是遇到比当前价格更高的就卖掉
if(prices.size() <=1) return 0;
int buy = INT_MAX, profit = 0;
for(int i=0; i<prices.size(); i++){
if(prices[i]<=buy) buy = prices[i];
else{
profit += prices[i]-buy;
buy = prices[i];
}
}
return profit;
}
};
上記のコードは、に簡略化することができます。
class Solution {
public:
int maxProfit(vector<int>& prices) {
if(prices.size() <=1) return 0;
int buy = INT_MAX, profit = 0;
for(int i=0; i<prices.size(); i++){
if(prices[i] > buy) profit += prices[i] - buy;// 只有当当前价格大于假设买入的价格时,才进行卖出
buy = prices[i];// 每次都在当前进行“假设”买入
}
return profit;
}
};
3. 2倍の最大の販売
\(buy1の\は)最初に表し\(私は\)あなたは初日購入するときに得ることができる最大の収入
\(buy2の\を)最初に表し\(私は\)二日目の購入時に利用できるようにします最大所得
\(sell1 \)第表す\(iは\)最大の利益の販売の最初の日ときに利用可能である
\(sell2の\)は最初表す\が(私は\)二日目の間に販売されてもよいです最大の利益
class Solution {
public:
int maxProfit(vector<int>& prices) {
// 最多只能买卖2次 求最大收益
// buy1 sell1 buy2 sell2 分别表示当前天如果是第一次买/卖、第二次买/卖时的最大收益
int buy1 = INT_MIN, buy2 = INT_MIN, sell1 = 0, sell2 = 0;
for(int price:prices){
sell2 = max(sell2, buy2+price);
buy2 = max(buy2, sell1-price);
sell1 = max(sell1, buy1+price);
buy1 = max(buy1, -price);
}
return sell2;
}
};
4.凍結された回の販売に制限はありません
\(\ [i]の購入)意味\(私は\)前の最後の行動に日購入され、最大の利益を
\(\ [i]の販売)意味\(私は\)前の最後の行動に日販売され、最大の利益を
\(\ [i]を休ま)意味\(私は\)日前の最後の行動には残り、最大の利益を凍結されます
\([I] = maxの購入(、RESTの購入[1-I。] [1-I。] -価格[i])と\)、MAX(iはi番目の日が売りで、日に凍結)
\(売り[I] = MAX(売り[1-i]は、購入する[1-i]が+価格[i])と\)、MAX(iはi番目の日は買いで、日に凍結)
\((売却、[I-1]を購入し、[I-1]休ま[I-1])\ [I] =最大を休ま)
class Solution {
public:
int maxProfit(vector<int>& prices) {
// 有冷冻期 不限制买卖次数 但是卖完股票后有一天的冷冻期才能再接着买
int n = prices.size();
if(n<=1) return 0;
vector<int> buy(n, INT_MIN), sell(n, INT_MIN), rest(n, INT_MIN);
buy[0] = -prices[0];
sell[0] = 0;
rest[0] = 0;
for(int i=1; i<n; i++){
buy[i] = max(buy[i-1], rest[i-1]-prices[i]);
sell[i] = max(sell[i-1], buy[i-1]+prices[i]);
rest[i] = max(rest[i-1], max(buy[i-1], sell[i-1]));
}
return max(buy[n-1], max(sell[n-1], rest[n-1]));
}
};