Best Time to Buy and Sell Stock with Transaction Fee

LeetCode problem 714. Best Time to Buy and Sell Stock with Transaction Fee.

## Problem description

You are given an array `prices` where `prices[i]` is the price of a given stock on the `ith` day, and an integer `fee` representing a transaction fee.

Find the maximum profit you can achieve. You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction.

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

Example 1
**Input:** prices = [1,3,2,8,4,9], fee = 2
**Output:** 8
**Explanation:** The maximum profit can be achieved by:
1. Buying at prices[0] = 1
2. Selling at prices[3] = 8
3. Buying at prices[4] = 4
4. Selling at prices[5] = 9

The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
Example 2
**Input:** prices = [1,3,7,5,10,3], fee = 3
**Output:** 6
Constraints
* `1 <= prices.length <= 5 * 104`
* `1 <= prices[i] < 5 * 104`
* `0 <= fee < 5 * 104`

## Problem analysis

This problem is similar to Best Time to Buy and Sell Stock II, except that for each transaction there will be a transaction fee subtracted from the profit from the transaction.

We can still use two variables `balance` and `maxProfit` to keep track of the maximum possible balance and profit at hand after each day. But, since we now have the transaction fee, the transition equations must be slightly modified to account for the transaction fee.

We first initialize `balance = -prices[0] - fee` and `maxProfit = 0`.

Then for days *i* = 1, 2, …, *n*-1, we update`balance` and `maxProfit`:

1. `balance = max(balance, maxProfit - (prices[i] + fee))`
	* `balance`: the maximum balance at hand if we do not purchase a new stock on day *i*.
	* `maxProfit - (prices[i] + fee)`: the maximum balance at hand if we do purchase a new stock on day *i*.
2. `maxProfit = max(maxProfit, balance + prices[i])`
	* `maxProfit`: the maximum profit we can make on day *i* if we do not sell the stock on day *i*.
	* `balance + prices[i]`: the maximum profit we can make on day *i* if we do sell the stock on day *i*.

Finally the `maxProfit` will be the result.

### Working example

* Input: prices = [5, 1, 2, 3, 7, 2, 5, 1, 3], fee = 2

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

* Return: **5**
	1. Buy on day 1 → sell on day 4 (profit: 4)
	2. Buy on day 5 → sell on day 6 (profit: 1)

### Complexity analysis

Time complexity
Since we have iterated through all the days, and the computation for each day is constant, the total time complexity is **O(n)**, where *n* is the total number of days.
Space complexity
Since we only used two variables `balance` and `maxProfit` and did not create additional data structures, the total space complexity is **O(1)**.
## Solution

### C++ solution

```
class Solution {
public:
 int maxProfit(std::vector<int>& prices, int fee) {
 // corner case
 const int len = prices.size();
 if (len <= 1) {
 return 0;
 }
 else if (len == 2) {
 return std::max(0, prices[1] - (prices[0] + fee));
 }

 int balance = -prices[0] - fee, maxProfit = 0;

 for (int i = 1; i < len; ++i) {
 // balance: if do not purchase new stock on day i
 // maxProfit - (prices[i] + fee): if purchase new stock on day i
 balance = std::max(balance, maxProfit - (prices[i] + fee));
 // maxProfit: if do not sell on day i
 // balance + prices[i]: if sell on day i
 maxProfit = std::max(maxProfit, balance + prices[i]);
 }

 return maxProfit;
 }
};

```

### Java solution

```
class Solution {
 public int maxProfit(int[] prices, int fee) {
 // corner case
 final int len = prices.length;
 if (len <= 1) {
 return 0;
 }
 else if (len == 2) {
 return Integer.max(0, prices[1] - (prices[0] + fee));
 }

 int balance = -prices[0] - fee, maxProfit = 0;

 for (int i = 1; i < len; ++i) {
 // balance: if do not purchase new stock on day i
 // maxProfit - (prices[i] + fee): if purchase new stock on day i
 balance = Integer.max(balance, maxProfit - (prices[i] + fee));
 // maxProfit: if do not sell on day i
 // balance + prices[i]: if sell on day i
 maxProfit = Integer.max(maxProfit, balance + prices[i]);
 }

 return maxProfit;
 }
}

```

## See also

* Best Time to Buy and Sell Stock II

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