New Problem Solution "Best Time to Buy and Sell Stock with Transaction Fee"
This commit is contained in:
parent
8bcae20e8a
commit
eaaf7574cd
@ -34,6 +34,7 @@ LeetCode
|
||||
|747|[Largest Number At Least Twice of Others](https://leetcode.com/problems/largest-number-at-least-twice-of-others/) | [Python](./algorithms/python/LargestNumberAtLeastTwiceOfOthers/dominantIndex.py)|Easy|
|
||||
|746|[Min Cost Climbing Stairs](https://leetcode.com/problems/min-cost-climbing-stairs/) | [Python](./algorithms/python/MinCostClimbingStairs/minCostClimbingStairs.py)|Easy|
|
||||
|717|[1-bit and 2-bit Characters](https://leetcode.com/problems/1-bit-and-2-bit-characters/) | [Python](./algorithms/python/1-bitAnd2-bitCharacters/isOneBitCharacter.py)|Easy|
|
||||
|714|[Best Time to Buy and Sell Stock with Transaction Fee](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee) | [C++](./algorithms/cpp/bestTimeToBuyAndSellStock/BestTimeToBuyAndSellStockWithTransactionFee.cpp)|Medium|
|
||||
|712|[Minimum ASCII Delete Sum for Two Strings](https://leetcode.com/problems/minimum-ascii-delete-sum-for-two-strings/) | [C++](./algorithms/cpp/minimumASCIIDeleteSumForTwoStrings/MinimumAsciiDeleteSumForTwoStrings.cpp)|Medium|
|
||||
|687|[Longest Univalue Path](https://leetcode.com/problems/longest-univalue-path/) | [Python](./algorithms/python/LongestUnivaluePath/longestUnivaluePath.py)|Easy|
|
||||
|684|[Redundant Connection](https://leetcode.com/problems/redundant-connection/) | [Python](./algorithms/python/RedundantConnection/findRedundantConnection.py)|Medium|
|
||||
|
@ -0,0 +1,201 @@
|
||||
// Source : https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee
|
||||
// Author : Hao Chen
|
||||
// Date : 2019-02-01
|
||||
|
||||
/*****************************************************************************************************
|
||||
*
|
||||
* Your are given an array of integers prices, for which the i-th element is the price of a given
|
||||
* stock on day i; and a non-negative integer fee representing a transaction fee.
|
||||
*
|
||||
* You may complete as many transactions as you like, but you need to pay the transaction fee for each
|
||||
* transaction. You may not buy more than 1 share of a stock at a time (ie. you must sell the stock
|
||||
* share before you buy again.)
|
||||
*
|
||||
* Return the maximum profit you can make.
|
||||
*
|
||||
* Example 1:
|
||||
*
|
||||
* Input: prices = [1, 3, 2, 8, 4, 9], fee = 2
|
||||
* Output: 8
|
||||
*
|
||||
* Explanation: The maximum profit can be achieved by:
|
||||
* Buying at prices[0] = 1Selling at prices[3] = 8Buying at prices[4] = 4Selling at prices[5] = 9The
|
||||
* total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
|
||||
*
|
||||
* Note:
|
||||
* 0 < prices.length <= 50000.
|
||||
* 0 < prices[i] < 50000.
|
||||
* 0 <= fee < 50000.
|
||||
******************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
class Solution {
|
||||
private:
|
||||
int max(int x, int y) {
|
||||
return x > y ? x: y;
|
||||
}
|
||||
int max(int x, int y, int z) {
|
||||
return max(x, max(y,z));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
int maxProfit(vector<int>& prices, int fee) {
|
||||
return maxProfit_dp03(prices, fee); // 100ms
|
||||
return maxProfit_dp02(prices, fee); // 100ms
|
||||
return maxProfit_dp01(prices, fee); // 2700ms
|
||||
}
|
||||
|
||||
// find the [buy-low, sell-high] prices pairs,
|
||||
// and remove the unnecessary prices.
|
||||
void genPricesPairs(vector<int> &prices, vector< pair<int, int> > &prices_pairs, int fee){
|
||||
|
||||
int low = -1;
|
||||
for (int i=0; i<prices.size()-1; i++){
|
||||
//meet the valley, then goes up
|
||||
if (prices[i] < prices[i+1] && low < 0 ) {
|
||||
low = i;
|
||||
}
|
||||
//meet the peak, then goes down
|
||||
if (prices[i] > prices[i+1] && low >= 0) {
|
||||
prices_pairs.push_back( make_pair( prices[low], prices[i]) );
|
||||
low = -1; // reset the `low` & `high`
|
||||
}
|
||||
}
|
||||
|
||||
// edge case
|
||||
if ( low >= 0 ) {
|
||||
prices_pairs.push_back( make_pair( prices[low], prices[prices.size()-1] ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int maxProfit_dp01(vector<int> &prices, int &fee) {
|
||||
|
||||
vector< pair<int, int> > prices_pairs;
|
||||
genPricesPairs(prices, prices_pairs, fee);
|
||||
|
||||
vector<int> dp(prices_pairs.size()+1, 0);
|
||||
|
||||
for (int i=0; i<prices_pairs.size(); i++) {
|
||||
for ( int j=0; j<=i; j++ ) {
|
||||
int profit = prices_pairs[i].second - prices_pairs[j].first - fee;
|
||||
// if the profit is negative, skip the transaction
|
||||
if ( profit < 0 ) profit = 0;
|
||||
dp[i+1] = max ( dp[i+1], dp[j] + profit);
|
||||
}
|
||||
}
|
||||
|
||||
return dp[dp.size()-1];
|
||||
}
|
||||
|
||||
int maxProfit_dp02(vector<int> &prices, int &fee) {
|
||||
|
||||
vector< pair<int, int> > prices_pairs;
|
||||
genPricesPairs(prices, prices_pairs, fee);
|
||||
|
||||
if ( prices_pairs.size() < 1 ) return 0;
|
||||
|
||||
|
||||
// first - represent the max profit if we buy.
|
||||
// second - represent the max profit if we sell.
|
||||
vector< pair<int,int> > dp(prices_pairs.size() , make_pair(0,0) );
|
||||
|
||||
//buy profit - if we buy it in day 0, then we got negtive profit.
|
||||
dp[0].first = - prices_pairs[0].first;
|
||||
|
||||
//sell profit - if we sell it in day 0, then we have the profits
|
||||
// if the profit is negtive, then won't sell it.
|
||||
dp[0].second = max(0, prices_pairs[0].second - prices_pairs[0].first - fee);
|
||||
|
||||
for (int i=1; i<prices_pairs.size(); i++) {
|
||||
// BUY - we could have three options
|
||||
// 1) hold the stock do nothing. profit = previous day's buy profit
|
||||
// 2) sell & buy. profit = previous sell profit - spent money to buy.
|
||||
// 3) fresh buy, give up the pervious buy, just buy it today.
|
||||
// find the max profit of these 3 options.
|
||||
|
||||
dp[i].first = max (dp[i-1].first, // option 1) do nothing
|
||||
dp[i-1].second - prices_pairs[i].first, // option 2) sell & buy
|
||||
- prices_pairs[i].first ); // option 3) fresh buy
|
||||
|
||||
// SELL - we could have three options
|
||||
// 1) hold the stock do nothing. profit = previous day's sell profit
|
||||
// 2) sell it. profit = previous day's buy + today's sell.
|
||||
// 3) sell previous and sell today. profit = previous's sell + today's sell
|
||||
// Find the max profit of these 3 options
|
||||
dp[i].second = max(dp[i-1].second,
|
||||
dp[i-1].first + prices_pairs[i].second - fee,
|
||||
dp[i-1].second + prices_pairs[i].second - prices_pairs[i].first - fee );
|
||||
}
|
||||
|
||||
return max( dp[dp.size()-1].second, 0 );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Actually, by given any day, we can have two status:
|
||||
// 1) BUY status - we can have two options at Day X.
|
||||
// i) buy stock - need previous sell status.(you cannot buy if you haven't sold)
|
||||
// ii) do nothing - need previous buy status.
|
||||
//
|
||||
// 2) SELL status - we can have two options at Day X.
|
||||
// i) sell stock - need previous buy status.(you cannot sell if you haven't bought)
|
||||
// ii) do nothing - keep the previous sell status.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// if we have [1,3,2,8,4,9], fee = 2
|
||||
// then we could have the following BUY & SELL status
|
||||
//
|
||||
// Day One
|
||||
// 1 - BUY: the profit is -1 ,becuase we spent 1 money
|
||||
// SELL: you cannot sell, the profit is 0.
|
||||
// Day Two
|
||||
// 3 - BUY : pre-SELL - 3 = -3, but do nothing has max profit pre-BUY: -1
|
||||
// SELL: pre-BUY + 3 -2 = -1+3-2 = 0 , the max profit: 0
|
||||
// Day Three
|
||||
// 2 - BUY : pre-SELL - 2 = 0 - 2 = -2, do nothing has max profit: -1
|
||||
// SELL: pre-BUY + 2 -2 = -1 + 2 -2 = -1, do nothing has max profit: 0
|
||||
// Day Four
|
||||
// 8 - BUY : pre-SELL - 8 = 0 - 8 = -8, so, just hold, the max buy profit: -1
|
||||
// SELL: pre-BUY + 8 - 2 = -1+8-2 =5, the max profit is 5
|
||||
// Day Five
|
||||
// 4 - BUY : pre-SELL - 4 = 5-4 = 1, do nothing profit is -1, so should buy it.
|
||||
// so, the max buy profit is 1.
|
||||
// SELL: pre-BUY + 4 -2 = -1 + 4 -2= 1, it's has lower profit than previous,
|
||||
// so, we won't sell, the max sell profit is 5.
|
||||
// Day Six
|
||||
// 9 - BUY : pre-SELL - 9 = 5-9= -4, so won't buy, the max buy profit is 1.
|
||||
// SELL: pre-BUY + 9 -2 = 1 + 9 -2 = 8, it's has higher profit. so we sell
|
||||
//
|
||||
// Let's use an table
|
||||
//
|
||||
// prices = 1, 3, 2, 8, 4, 9
|
||||
// max buy profit = -1, -1, -1, -1, 1, 5
|
||||
// max sell profit = 0, 0, 0, 5, 5, 8
|
||||
//
|
||||
// We can see we keep tracking the max buy and sell profit for everyday.
|
||||
//
|
||||
// buy[i] = max( buy[i-1], // do nothing
|
||||
// sell[i-1] - prices[i] ); // sell in previous day can buy today
|
||||
//
|
||||
// sell[i] = max( sell[i-1], // do nothing
|
||||
// buy[i-1] + prices[i] - fee ); // sell today
|
||||
//
|
||||
int maxProfit_dp03(vector<int> &prices, int &fee) {
|
||||
int buy=-prices[0], sell=0;
|
||||
int pre_buy=0, pre_sell=0;
|
||||
|
||||
for(auto price: prices) {
|
||||
pre_buy = buy;
|
||||
buy = max (sell - price, pre_buy);
|
||||
|
||||
pre_sell = sell;
|
||||
sell = max( pre_buy + price - fee, pre_sell);
|
||||
}
|
||||
|
||||
return sell;
|
||||
}
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user