Advertisement
i_love_rao_khushboo

Best Time to Buy and Sell Stock III

Sep 18th, 2022
787
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.56 KB | None | 0 0
  1. // Problem link: https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/
  2.  
  3. // Useful Reference(s): --->
  4. // https://medium.com/algorithms-and-leetcode/best-time-to-buy-sell-stocks-on-leetcode-the-ultimate-guide-ce420259b323
  5.  
  6. /*********************************************************************************************************/
  7.  
  8. // Method 1 (Top Down DP - 3D) (using a 3D vector)
  9.  
  10. /* # In this approach our dp is defined by 3 states (that's why 3D DP)
  11.    # State-1(bought): This shows if the stock just previous to current stock was bought or not
  12.                       We will have max 2 possibilities in this, even though we have 3 choices (skip/buy/sell the current stock)
  13.    # State-2(t): This shows the atmost #transactions we can make from current position to the last of prices array.
  14.                  So there will be 3 values for this (0/1/2).
  15.    # State-3(pos): It shows the current position of stock prices which we are working on.                  
  16. */
  17.  
  18. #include<bits/stdc++.h>
  19. using namespace std;
  20.  
  21. vector<vector<vector<int>>> dp;
  22.  
  23. int solve(bool bought, int t, int pos, int n, vector<int> &v) {
  24.     // base case
  25.     // if out of bounds or if #transactions = 0, then profit which
  26.     // can be achieved = 0
  27.     if(pos >= n || t == 0) return 0;
  28.    
  29.     // check if already calculated or not
  30.     if(dp[bought][t][pos] != -1) return dp[bought][t][pos];
  31.    
  32.     // Now we have 3 choices (skip, buy or sell the current share according to
  33.     // previous call)
  34.    
  35.     // Case: if we skip the current element
  36.     int ans = solve(bought, t, pos + 1, n, v);
  37.    
  38.     // Case: if we sell the current element
  39.     if(bought) ans = max(ans, v[pos] + solve(false, t - 1, pos + 1, n, v));
  40.    
  41.     // Case: if we buy the current element
  42.     else ans = max(ans, -v[pos] + solve(true, t, pos + 1, n, v));
  43.    
  44.     // return by taking whichever is maximum
  45.     return dp[bought][t][pos] = ans;
  46. }
  47.  
  48. int maxProfit(vector<int> &prices) {
  49.     vector<int> v = prices;
  50.     int n = v.size();
  51.    
  52.     dp.resize(2, vector<vector<int>>(3, vector<int>(n, -1)));
  53.     return solve(false, 2, 0, n, v);
  54. }
  55.  
  56. int main()
  57. {
  58.     ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  59.     srand(chrono::high_resolution_clock::now().time_since_epoch().count());
  60.  
  61.     // #ifndef ONLINE_JUDGE
  62.     //     freopen("input.txt", "r", stdin);
  63.     //     freopen("output.txt", "w", stdout);
  64.     // #endif
  65.  
  66.     vector<int> prices {7, 1, 5, 3, 6, 4};
  67.     cout << maxProfit(prices);
  68.  
  69.     return 0;
  70. }
  71.  
  72. // Time complexity: O(n)
  73. // Space complexity: O(n), where n = size of input array
  74.  
  75. /*********************************************************************************************************/
  76.  
  77. // Method 2 (Top Down DP - 3D) (using a unordered_map instead of a 3D table for lookup)
  78. // This method may give TLE in some of the cases as the lookup of a string in the unordered map
  79. // will not take constant time as in Method 1 above.
  80.  
  81. #include<bits/stdc++.h>
  82. using namespace std;
  83.  
  84. unordered_map<string, int> dp;
  85.  
  86. int solve(bool bought, int t, int pos, int n, vector<int> &v) {
  87.     // base case
  88.     // if out of bounds or if #transactions = 0, then profit which
  89.     // can be achieved = 0
  90.     if(pos >= n || t == 0) return 0;
  91.    
  92.     // check if already calculated or not
  93.     string key = to_string(bought) + to_string(t) + to_string(pos);
  94.     if(dp.count(key) != 0) return dp[key];
  95.    
  96.     // Now we have 3 choices (skip, buy or sell the current share according to
  97.     // previous call)
  98.    
  99.     // Case: if we skip the current element
  100.     int ans = solve(bought, t, pos + 1, n, v);
  101.    
  102.     // Case: if we sell the current element
  103.     if(bought) ans = max(ans, v[pos] + solve(false, t - 1, pos + 1, n, v));
  104.    
  105.     // Case: if we buy the current element
  106.     else ans = max(ans, -v[pos] + solve(true, t, pos + 1, n, v));
  107.    
  108.     // return by taking whichever is maximum
  109.     return dp[key] = ans;
  110. }
  111.  
  112. int maxProfit(vector<int> &prices) {
  113.     vector<int> v = prices;
  114.     int n = v.size();
  115.    
  116.     return solve(false, 2, 0, n, v);
  117. }
  118.  
  119. int main()
  120. {
  121.     ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  122.     srand(chrono::high_resolution_clock::now().time_since_epoch().count());
  123.  
  124.     // #ifndef ONLINE_JUDGE
  125.     //     freopen("input.txt", "r", stdin);
  126.     //     freopen("output.txt", "w", stdout);
  127.     // #endif
  128.  
  129.     vector<int> prices {7, 1, 5, 3, 6, 4};
  130.     cout << maxProfit(prices);
  131.  
  132.     return 0;
  133. }
  134.  
  135. // This method is not as efficient in terms of time as compared to Method 1, but it is more efficient
  136. // in terms of space as against Method 1.
  137.  
  138. /**********************************************************************************************************/
  139.  
  140. // Method 3 (Divide & Conquer)
  141. // Explanation of the approach: https://www.youtube.com/watch?v=37s1_xBiqH0
  142.  
  143. #include<bits/stdc++.h>
  144. using namespace std;
  145.  
  146. int solve(int n, vector<int> &v) {
  147.     // left[i] will store the max profit we can gain from v[0] to v[i] (both inclusive)
  148.     // by performing at most 1 transaction
  149.     vector<int> left(n, 0);
  150.    
  151.     // right[i] will store the max profit we can gain from v[n - 1] to v[i] (both inclusive)
  152.     // by performing at most 1 transaction
  153.     vector<int> right(n, 0);
  154.    
  155.     // prerocessing the left array
  156.     // considering each v[i] as a selling point & maintaining
  157.     // a running MINIMUM stock price
  158.     int left_min = v[0];
  159.     for(int i = 1; i < n; i++) {
  160.         left[i] = max(left[i - 1], v[i] - left_min);
  161.         left_min = min(left_min, v[i]);
  162.     }
  163.    
  164.     // preprocessing the right array
  165.     // considering each v[i] as a buying point & maintaining
  166.     // a running MAXIMUM stock price
  167.     int right_max = v[n - 1];
  168.     for(int i = (n - 2); i >= 0; i--) {
  169.         right[i] = max(right[i + 1], right_max - v[i]);
  170.         right_max = max(right_max, v[i]);
  171.     }
  172.    
  173.     // using divide and conquer approach
  174.     // we divide the whole array in 2 parts at each element v[i]
  175.     // in the left part we include elements from v[0] to v[i - 1]
  176.     // in the right part we include elements from v[i] to v[n - 1]
  177.     int profit = right[0];
  178.     for(int i = 1; i < n; i++) {
  179.         profit = max(profit, left[i - 1] + right[i]);
  180.     }
  181.    
  182.     return profit;
  183. }
  184.  
  185. int maxProfit(vector<int> &prices) {
  186.     vector<int> v = prices;
  187.     int n = v.size();
  188.     if(n == 0) return 0;
  189.    
  190.     return solve(n, v);
  191. }
  192.  
  193. int main()
  194. {
  195.     ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  196.     srand(chrono::high_resolution_clock::now().time_since_epoch().count());
  197.  
  198.     // #ifndef ONLINE_JUDGE
  199.     //     freopen("input.txt", "r", stdin);
  200.     //     freopen("output.txt", "w", stdout);
  201.     // #endif
  202.  
  203.     vector<int> prices {7, 1, 5, 3, 6, 4};
  204.     cout << maxProfit(prices);
  205.  
  206.     return 0;
  207. }
  208.  
  209. // Time complexity: O(n)
  210. // Space complexity: O(n), where n = size of input array
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement