Best Time to Buy and Sell Stock II

LeetCode problem 122: Best Time to Buy and Sell Stock II.

## Problem description

You are given an array `prices` where `prices[i]` is the price of a given stock on the `ith` day.

Find the maximum profit you can achieve. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times).

**Note:** You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again).

Example 1
**Input:** prices = [7,1,5,3,6,4]
**Output:** 7
**Explanation:** Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4. Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3.
Example 2
**Input:** prices = [1,2,3,4,5]
**Output:** 4
**Explanation:** Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are engaging multiple transactions at the same time. You must sell before buying again.

Example 3
**Input:** prices = [7,6,4,3,1]
**Output:** 0
**Explanation:** In this case, no transaction is done, i.e., max profit = 0.
Constraints
* `1 <= prices.length <= 3 * 104`
* `0 <= prices[i] <= 104`

## Problem analysis

Similar to the Best Time to Buy and Sell Stock problem, we use a `balance` variable to keep track of the balance at hand after completing a half-transaction (i.e. only buying, no selling), and a `maxProfit` variable to keep track of the maximum profit we can gain. But one major difference is that we use `balance` to keep track of the maximum balance possible after completing 0.5, 1.5, 2.5, … transactions; but in this problem the actual number of transactions is irrelevant, so we don't keep track of it.

To start with, we initialize `maxProfit` to 0, the profit we can get under the worst case; we initialize `balance` to `INT_MIN`, since we want to keep increasing the balance as we iterate from left to right.

For each day we can choose one action among the three:

* Do nothing
* Purchase a new stock (not applicable on the last day)
* Sell a stock (not applicable on the first day; only available when we have it at hand)

Just like in the Best Time to Buy and Sell Stock problem, we iterate from left to right and, in each iteration, update the `maxProfit` and `balance` variables as follows:

1. For `maxProfit`: `maxProfit = std::max(maxProfit, balance + prices[i])`
	* If we do not sell on day *i*, then our profit is still `maxProfit` from the previous day.
	* If we do sell on day *i*, then our profit would be `balance + prices[i]`. Pick whichever option yielding greater profit.
2. For `balance`: `balance = std::max(balance, maxProfit - prices[i])`
	* If we do not buy on day *i*, then our balance is still `balance` from the previous day.
	* If we do buy on day *i*, then our balance would be `maxProfit - prices[i]`. Pick whichever option yielding greater balance at our hand.

After looping through all the prices, we return `maxProfit` as the result.

### Working example

* Input: 5, 1, 2, 3, 7, 2, 5, 1, 3

 `balance` (after each iteration)
 `maxProfit` (after each iteration)

* Return: **11**
	1. Buy on day 1 → sell on day 4 (profit: 6; total profit: 6)
	2. Buy on day 5 → sell on day 6 (profit: 3; total profit: 9)
	3. Buy on day 7 → sell on day 8 (profit: 2; total profit: 11)

### Complexity analysis

Time complexity
We do the problem one-pass. When iterating on the price of each day, we update the `balance` and `maxProfit` exactly once during each iteration, with O(1) time complexity for each of them. So the total time complexity is **O(n)**, where *n* is the number of days.
Space complexity
Since we did not allocate additional data structures, the space complexity is **O(1)**.
## Solution

### C++ solution

```
class Solution {
public:
 int maxProfit(std::vector<int>& prices) {
 const int days = prices.size();
 if (days < 2) {
 return 0;
 }

 int balance = INT\_MIN, maxProfit = 0;
 for (const int& i: prices) {
 // maxProfit: profit if we do not sell on day i
 // balance + i: profit if we do sell on day i
 maxProfit = std::max(maxProfit, balance + i);
 // balance: if we do not purchase new stock on day i
 // maxProfit - i: if we do purchase new stock on day i
 balance = std::max(balance, maxProfit - i);
 }

 return maxProfit;
 }
};

```

### Java solution

```
class Solution {
 public int maxProfit(int[] prices) {
 final int days = prices.length;
 if (days < 2) {
 return 0;
 }

 int balance = Integer.MIN\_VALUE, maxProfit = 0;
 for (int i: prices) {
 // maxProfit: profit if we do not sell on day i
 // balance + i: profit if we do sell on day i
 maxProfit = Math.max(maxProfit, balance + i);
 // balance: if we do not purchase new stock on day i
 // maxProfit - i: if we do purchase new stock on day i
 balance = Math.max(balance, maxProfit - i);
 }

 return maxProfit;
 }
}

```

## See also

* Best Time to Buy and Sell Stock with Cooldown
* Best Time to Buy and Sell Stock with Transaction Fee

Best time to buy and sell stock
 122
 123
 188
 309
 714