五道股票題總結:
121 買賣股票的最佳時機
122 買賣股票的最佳時機
124 買賣股票的最佳時機4
309 最佳股票買賣含冷凍期
714 買賣股票的最佳時機含有手續費
121 買賣股票的最佳時機
給定一個數組,它的第 i 個元素是一支給定股票第 i 天的價格。
如果你最多只允許完成一筆交易(即買入和賣出一支股票),設計一個算法來計算你所能獲取的最大利潤。
注意你不能在買入股票前賣出股票。
示例 1:
輸入: [7,1,5,3,6,4]
輸出: 5
解釋: 在第 2 天(股票價格 = 1)的時候買入,在第 5 天(股票價格 = 6)的時候賣出,最大利潤 = 6-1 = 5 。
注意利潤不能是 7-1 = 6, 因為賣出價格需要大於買入價格。
示例 2:
輸入: [7,6,4,3,1]
輸出: 0
解釋: 在這種情況下, 沒有交易完成, 所以最大利潤為 0。
// Solution 1 dp[i] 代表以i結尾的最大利潤 class Solution { int[] dp ; public int maxProfit(int[] prices) { if(prices.length == 0 ) return 0; dp = new int [prices.length + 2]; Arrays.fill(dp,0); int min = prices[0]; for( int i=1; i<prices.length; i++){ if(prices[i-1] < min) { min = prices[i-1]; } dp[i] = prices[i] - min; } int ans = 0 ; for(int i=0; i<prices.length; i++){ ans = Math.max(ans, dp[i]); } return ans; } };
122 買賣股票的最佳時機
給定一個數組,它的第 i 個元素是一支給定股票第 i 天的價格。
設計一個算法來計算你所能獲取的最大利潤。你可以盡可能地完成更多的交易(多次買賣一支股票)。
注意:你不能同時參與多筆交易(你必須在再次購買前出售掉之前的股票)。
示例 1:
輸入: [7,1,5,3,6,4]
輸出: 7
解釋: 在第 2 天(股票價格 = 1)的時候買入,在第 3 天(股票價格 = 5)的時候賣出, 這筆交易所能獲得利潤 = 5-1 = 4 。
隨后,在第 4 天(股票價格 = 3)的時候買入,在第 5 天(股票價格 = 6)的時候賣出, 這筆交易所能獲得利潤 = 6-3 = 3 。
示例 2:
輸入: [1,2,3,4,5]
輸出: 4
解釋: 在第 1 天(股票價格 = 1)的時候買入,在第 5 天 (股票價格 = 5)的時候賣出, 這筆交易所能獲得利潤 = 5-1 = 4 。
注意你不能在第 1 天和第 2 天接連購買股票,之后再將它們賣出。
因為這樣屬於同時參與了多筆交易,你必須在再次購買前出售掉之前的股票。
示例 3:
輸入: [7,6,4,3,1]
輸出: 0
解釋: 在這種情況下, 沒有交易完成, 所以最大利潤為 0。
class Solution { public int maxProfit(int[] prices) { // solution 1 // int Length = prices.length; // if(Length == 0 ){ // return 0; // } // int[] buy = new int[Length]; // int[] s1 = new int[Length]; // int[] sell = new int[Length]; // int[] s2 = new int[Length]; // buy[0] = -prices[0]; // s1[0] = -prices[0]; // for(int i=1; i<Length;i++){ // buy[i] = Math.max(s2[i-1], sell[i-1]) - prices[i]; // s1[i] = Math.max(s1[i-1],buy[i-1]); // sell[i] = Math.max(buy[i-1], s1[i-1]) + prices[i]; // s2[i] = Math.max( s2[i-1], sell[i-1]); // } // return Math.max( sell[Length-1], s2[Length-1]); //solution 2 int Length = prices.length; if(Length == 0 ){ return 0; } int ans = 0 ; for(int i=1 ; i< Length; i++){ if( prices[i] > prices[i-1] ){ ans += (prices[i] - prices[i-1]); } } return ans ; } }
124 買賣股票的最佳時機4
給定一個數組,它的第 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 。
class Solution { public int maxProfitInfinte(int[] prices) { int Length = prices.length; if(Length == 0 ){ return 0; } int ans = 0 ; for(int i=1 ; i< Length; i++){ if( prices[i] > prices[i-1] ){ ans += (prices[i] - prices[i-1]); } } return ans ; } public int maxProfit(int k, int[] prices) { int Length = prices.length; if(Length == 0 || Length == 1 ){ return 0; } if( k > Length >> 1 ){ return maxProfitInfinte( prices); } int[] buy = new int[Length]; int[] sell = new int[Length]; for(int j=1; j<=k; j++) { buy[j] = Integer.MIN_VALUE; } // buy[j]代表進行了j詞交易,最后一次為買時能獲取的最大利潤
for(int i=0;i<Length;i++){ for (int j = 1; j<=k; j++) { buy[j] = Math.max(buy[j], sell[j-1] - prices[i]); sell[j] = Math.max(buy[j] + prices[i], sell[j]); } } return sell[k] ; } }
309 最佳股票買賣含冷凍期
給定一個整數數組,其中第 i 個元素代表了第 i 天的股票價格 。
設計一個算法計算出最大利潤。在滿足以下約束條件下,你可以盡可能地完成更多的交易(多次買賣一支股票):
你不能同時參與多筆交易(你必須在再次購買前出售掉之前的股票)。
賣出股票后,你無法在第二天買入股票 (即冷凍期為 1 天)。
示例:
輸入: [1,2,3,0,2]
輸出: 3
解釋: 對應的交易狀態為: [買入, 賣出, 冷凍期, 買入, 賣出]
class Solution { public int maxProfit(int[] prices) { // int length = prices.length; // if(length == 0 ){ // return 0 ; // } // int[] buy = new int[length]; // int[] sell = new int[length]; // int[] none = new int[length]; // int[] sequeze = new int[length]; // buy[0] = -prices[0]; // sell[0] = 0; // none[0] = -prices[0] ; // sequeze[0] = 0 ; // for(int i=1; i<length; i++ ){ // buy[i] = sequeze[i-1] - prices[i] ; // none[i] = Math.max(none[i-1] , buy[i-1] ) ; // sell[i] = Math.max( buy[i-1] , none[i-1] ) + prices[i] ; // sequeze[i] = Math.max(sequeze[i-1], sell[i-1]) ; // } // return Math.max(sequeze[ length -1 ] , sell[ length -1 ]); } }
714 買賣股票的最佳時機含有手續費
給定一個整數數組 prices,其中第 i 個元素代表了第 i 天的股票價格 ;非負整數 fee 代表了交易股票的手續費用。
你可以無限次地完成交易,但是你每次交易都需要付手續費。如果你已經購買了一個股票,在賣出它之前你就不能再繼續購買股票了。
返回獲得利潤的最大值。
示例 1:
輸入: prices = [1, 3, 2, 8, 4, 9], fee = 2
輸出: 8
解釋: 能夠達到的最大利潤:
在此處買入 prices[0] = 1
在此處賣出 prices[3] = 8
在此處買入 prices[4] = 4
在此處賣出 prices[5] = 9
總利潤: ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
注意:
0 < prices.length <= 50000.
0 < prices[i] < 50000.
0 <= fee < 50000.
class Solution { public int maxProfit( int[] prices, int fee) { int Length = prices.length; if(Length == 0 || Length == 1 ){ return 0; } int[] buy = new int[Length]; int[] sell = new int[Length]; buy[0] = -prices[0]; //sell[i] 代表以i物品結束交易的獲取的最大利潤 //buy[i] 代表買第i個物品獲取的最大利潤 for(int i=1 ; i<Length;i++){ buy[i] = Math.max( buy[i-1],sell[i-1] - prices[i]) ; sell[i] = Math.max( sell[i-1] , buy[i-1] + prices[i] - fee ); } return sell[Length-1] ; } }