# Java description LeetCode, 123. Best Time to Buy and Sell Stock III

Keywords: Java leetcode

Hello, I'm hehaige. I focus on the back end. If I can, I want to be a code designer instead of an ordinary coder to witness the growth of hehaige. Your comments and praise are my biggest motivation.

## 1-1: title

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 at most two transactions.

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

Example 1:

```Input: prices = [3,3,5,0,0,3,1,4]
Output: 6
Explanation: Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 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.
```

Example 4:

```Input: prices = [1]
Output: 0
```

Constraints:

```1 <= prices.length <= 105
0 <= prices[i] <= 105
```

Source: LeetCode

## 1-2: idea

• Train of thought 1: there is the answer to question 2. The idea of holding stocks as a state. I wonder if I can add another dimension to represent the number of transactions, so as to ensure that the second transaction must be after the first transaction. Then I wrote a code according to this idea. Facts have proved that it is still relatively complex. Especially when initializing, if I don't think well, one can't ac.
• Train of thought 2: there are five kinds of trading situations on a certain day
```- No operation, no buying or selling
- First purchase
- First sale
- Second purchase
- Second sale
```
Then dp[i][j] can be used to represent the income in the j-th state on the i-th day. It should be noted here. For example, if you are in the state of second buying, it does not necessarily mean that you must buy on that day, or you may have bought for the second time before, but you didn't buy on that day. For example, [buy, no, sell, no, no, no, buy, no, no, I] then I is also in the second buying state, because I have bought twice before, and I cannot be sold in i+1 day.

## 1-3: idea1 code

```public static int maxProfit(int[] prices) {
int n = prices.length;
// dp[i][j][k] represents whether to hold shares [0,1] on day i[1,n], and the maximum income of the k[0,2] transaction. It is specified that the number of transactions at the time of sale + 1
int[][][] dp = new int[n + 1][2][3];

for (int k = 0; k <= 2; k++) {
dp[1][0][k] = 0;
dp[1][1][k] = -prices[0];
}

for (int i = 2; i < n + 1; i++) {
int price = prices[i - 1];
for (int j = 0; j <= 2; j++) {
// Transaction 0
if (j == 0) {
dp[i][0][j] = dp[i - 1][0][j];
} else {
// Not held today = max (not held yesterday, held yesterday + sold today). The held yesterday must be the last transaction, so here j is to be - 1
dp[i][0][j] = Math.max(dp[i - 1][0][j], dp[i - 1][1][j - 1] + price);
}
// Today's holding = max (held yesterday, not held yesterday + bought today), not held yesterday, held today, is still a transaction, j don't move.
dp[i][1][j] = Math.max(dp[i - 1][1][j], dp[i - 1][0][j] - price);
}
}
List<Integer> list = new ArrayList<>();
System.out.println(Arrays.deepToString(dp));
for (int i = 0; i <= 1; i++) {
for (int j = 0; j <= 2; j++) {
// dp[n][0][0], dp[n][1][0], dp[n][0][1], dp[n][1][1], dp[n][0][2], dp[n][1][2]
}
}
return Collections.max(list);
}
```

There are several points to note:

• This code is simplified. You can list the dp state transition equation when j=0, 1 and 2, and then simplify it. I couldn't write it directly with j inner loop at the beginning.
• Location of maximum value: there are skills to find the maximum value at last, but I didn't expect that the last time I sold it was the location of the maximum value.
• Initialization: initialization is also a little difficult. At first, I felt that buying on the same day and selling on the same day did not meet the meaning of the topic. The topic said that buying on the same day could not be sold on the same day, which should not exist. However, after reading the answer, buying on the same day and selling on the same day will not affect the final result, such as dp[1][0][2] = 0; The first day did not hold stocks, and it was the second time to sell, that is, buy, sell, these all happened on the same day.

## 1-4: idea2 code

```public static int maxProfit2(int[] prices) {
int n = prices.length;
// dp[i][j] stands for day I,
// j represents the state of day i, five in total.
// -0: no transaction on that day
// -1: first purchase
// -2: first sale
// -3: second purchase
// -4: second sale
int[][] dp = new int[n + 1][5];

// initialization
for (int i = 0; i < dp[0].length; i++) {
if (i % 2 == 1) {
dp[1][i] = -prices[0];
}
}
for (int i = 2; i < n + 1; i++) {
int price = prices[i - 1];
dp[i][0] = dp[i - 1][0];
for (int j = 1; j <= 4; j++) {
// j is odd
if (j % 2 == 1) {
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - 1] - price);
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - 1] + price);
}
}
//            //The first purchase on day i = max (no operation on that day, buy on that day), dp[i - 1][0] represents the maximum income without operation on the previous day. You can't buy for the first time if you are not in no operation state.
//            dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - price);
//            //The first sale on day i = max (no operation on that day, sell on that day), dp[i - 1][1] represents the maximum income in the buying state of the previous day. If you are not in the buying state, you cannot buy for the first time.
//            dp[i][2] = Math.max(dp[i - 1][2], dp[i - 1][1] + price);
//            dp[i][3] = Math.max(dp[i - 1][3], dp[i - 1][2] - price);
//            dp[i][4] = Math.max(dp[i - 1][4], dp[i - 1][3] + price);
}
System.out.println(Arrays.deepToString(dp));
return dp[n][4];
}
```

The notes here are detailed enough that I have written all the dp state transition equations. It should be easier to understand. Initialization is the same idea as before. We can use the idea of rolling array to give the second version:

```public static int maxProfit3(int[] prices) {
int n = prices.length;
// dp[i][j] stands for day I,
// j represents the state of day i, five in total.
// -0: no transaction on that day
// -1: first purchase
// -2: first sale
// -3: second purchase
// -4: second sale
int[][] dp = new int[n + 1][5];
int nothing = 0;
int sell1 = 0;
int sell2 = 0;

for (int i = 2; i < n + 1; i++) {
int price = prices[i - 1];
sell1 = Math.max(sell1, buy1 + price);