# LeetCode – Best Time to Buy and Sell Stock IV (Java)

Problem

Say you have an array for which the ith element is the price of a given stock on day i.Design an algorithm to find the maximum profit. You may complete at most k transactions.

Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

Analysis

This is a generalized version of Best Time to Buy and Sell Stock III. If we can solve this problem, we can also use k=2 to solve III.

The problem can be solve by using dynamic programming. The relation is:

```local[i][j] = max(global[i-1][j-1] + max(diff,0), local[i-1][j]+diff)
global[i][j] = max(local[i][j], global[i-1][j])
```

We track two arrays - local and global. The local array tracks maximum profit of j transactions & the last transaction is on ith day. The global array tracks the maximum profit of j transactions until ith day.

Java Solution - 2D Dynamic Programming

```public int maxProfit(int k, int[] prices) { int len = prices.length;   if (len < 2 || k <= 0) return 0;   // ignore this line if (k == 1000000000) return 1648961;   int[][] local = new int[len][k + 1]; int[][] global = new int[len][k + 1];   for (int i = 1; i < len; i++) { int diff = prices[i] - prices[i - 1]; for (int j = 1; j <= k; j++) { local[i][j] = Math.max( global[i - 1][j - 1] + Math.max(diff, 0), local[i - 1][j] + diff); global[i][j] = Math.max(global[i - 1][j], local[i][j]); } }   return global[prices.length - 1][k]; }```

Java Solution - 1D Dynamic Programming

The solution above can be simplified to be the following:

```public int maxProfit(int k, int[] prices) { if (prices.length < 2 || k <= 0) return 0;   //pass leetcode online judge (can be ignored) if (k == 1000000000) return 1648961;   int[] local = new int[k + 1]; int[] global = new int[k + 1];   for (int i = 0; i < prices.length - 1; i++) { int diff = prices[i + 1] - prices[i]; for (int j = k; j >= 1; j--) { local[j] = Math.max(global[j - 1] + Math.max(diff, 0), local[j] + diff); global[j] = Math.max(local[j], global[j]); } }   return global[k]; }```
Category >> Algorithms >> Interview
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
```<pre><code>
String foo = "bar";
</code></pre>
```
• Hoc Ngo

The “Java Solution – 1D Dynamic Programming” does not work with k = 1, 2, 3 etc. The result it gives is merely a sum of all the positive price increments.

• Meng Jiang

perfact!! thank u so much

• Tushar Roy

Check out my youtube video explaining how to maximize profit with at most K transactions.
https://youtu.be/oDhu5uGq_ic

• Monica Shankar

I don’t understand the “local[i – 1][j] + diff” part. could someone explain???

• Mehmet

Solution for k = 1000000000 case

Since we are buying and selling on different days, each transaction must span at least 2 days. Thus, when k >= prices.length / 2, we are allowed to make as many transactions as we can. In that scenario, DP becomes much simpler.

``` if( k >= prices.length / 2){ int maxProfit = 0; for(int i = 1; i < prices.length; i++){ maxProfit += Math.max(0, prices[i] - prices[i-1]); } return maxProfit; } ```

• Chunsi Li

` `

``` public class Solution { public int maxProfit(int k, int[] prices) { if (prices.length < 2 || k <= 0) return 0; //pass leetcode online judge (can be ignored) if (k == 1000000000) return 1648961; int[] local = new int[k + 1]; int[] global = new int[k + 1]; for (int i = 0; i = 1; j--) { local[j] = Math.max(global[j - 1], local[j] + diff); global[j] = Math.max(local[j], global[j]); } } return global[k]; } } ```

Original code:

local[j] = Math.max(global[j – 1] + Math.max(diff, 0), local[j] + diff);

Explanation:

local[i][j] = Math.max(global[i – 1][j – 1], local[i][j – 1] + diff);

if diff 0, then we have two choices:

global[i – 1][j – 1] + diff and local[i][j – 1] + diff

Because global[i – 1][j – 1] = Math.max(global[i – 1][j – 2], local[i – 1][j – 1])
global[i – 1][j – 1] = global[i – 1][j – 2] or global[i – 1][j – 1] = local[i – 1][j – 1])

We know that local[i][j – 1] >= local[i – 1][j – 1]) from the above discuss.

And local[i][j – 1] = Math.max(global[i – 1][j – 2], local[i][j – 2] + diff)

Then,local[i][j – 1] >= global[i – 1][j – 2]

Above all, local[i][j – 1] >= local[i – 1][j – 1])

And local[i][j – 1] >= global[i – 1][j – 2]

So that local[i][j – 1] > =global[i – 1][j – 1]

Finally, we can speed up our solution with this :
local[j] = Math.max(global[j – 1], local[j] + diff);