Given the 0-indexed arrays prices and profits of length n. There are
n items in an store where the ith item has a price of prices[i] and a profit of profits[i].
We have to pick three items with the following condition:
prices[i] < prices[j] < prices[k] where i < j < k.
If we pick items with indices i, j and k satisfying the above condition, the profit would be profits[i] + profits[j] + profits[k].
Return _themaximum profit we can get, and _-1if it ’s not possible to pick three items with the given condition.
Input: prices =[10,2,3,4], profits =[100,2,7,10]Output: 19Explanation: We can't pick the item with index i=0 since there are no indices j and k such that the condition holds.So the only triplet we can pick, are the items with indices 1,2 and 3 and it's a valid pick since prices[1]< prices[2]< prices[3].The answer would be sum of their profits which is2+7+10=19.
Example 2:
1
2
3
4
5
Input: prices =[1,2,3,4,5], profits =[1,5,3,4,6]Output: 15Explanation: We can select any triplet of items since for each triplet of indices i, j and k such that i < j < k, the condition holds.Therefore the maximum profit we can get would be the 3 most profitable items which are indices 1,3 and 4.The answer would be sum of their profits which is5+4+6=15.
Example 3:
1
2
3
Input: prices =[4,3,2,1], profits =[33,20,19,87]Output: -1Explanation: We can't select any triplet of indices such that the condition holds, so we return-1.
We want to find three indices i < j < k such that prices[i] < prices[j] < prices[k] and maximize profits[i] + profits[j] + profits[k]. Unlike the brute force approach, we can use dynamic programming and segment trees (or BIT) to efficiently find the best left and right profits for each middle index.
Coordinate compress the prices to allow efficient indexing in segment trees/BIT.
For each index j, find the maximum profit for a valid i < j with prices[i] < prices[j] (left best) and for k > j with prices[k] > prices[j] (right best).
Use a segment tree/BIT to maintain and query the best profit for left and right efficiently.
For each j, if both left and right exist, update the answer with left + profits[j] + right.
Return the maximum profit found, or -1 if no valid triplet exists.
classSolution {
publicintmaxProfit(int[] prices, int[] profits) {
int n = prices.length;
int[] sorted = prices.clone();
Arrays.sort(sorted);
int m = 0;
for (int i = 0; i < n; i++) if (m == 0 || sorted[m-1]!= sorted[i]) sorted[m++]= sorted[i];
int[] left =newint[n], right =newint[n];
Arrays.fill(left, -1); Arrays.fill(right, -1);
int[] bit =newint[m+2];
Arrays.fill(bit, -1);
for (int j = 0; j < n; j++) {
int idx = Arrays.binarySearch(sorted, 0, m, prices[j]);
int l = idx;
int best =-1;
for (int i = l; i > 0; i -= i &-i) best = Math.max(best, bit[i]);
left[j]= best;
for (int i = l+1; i < bit.length; i += i &-i) bit[i]= Math.max(bit[i], profits[j]);
}
Arrays.fill(bit, -1);
for (int j = n-1; j >= 0; j--) {
int idx = Arrays.binarySearch(sorted, 0, m, prices[j]);
int l = m - idx - 1;
int best =-1;
for (int i = l; i > 0; i -= i &-i) best = Math.max(best, bit[i]);
right[j]= best;
for (int i = l+1; i < bit.length; i += i &-i) bit[i]= Math.max(bit[i], profits[j]);
}
int ans =-1;
for (int j = 0; j < n; j++) {
if (left[j]!=-1 && right[j]!=-1) {
ans = Math.max(ans, left[j]+ profits[j]+ right[j]);
}
}
return ans;
}
}
classSolution {
funmaxProfit(prices: IntArray, profits: IntArray): Int {
val n = prices.size
val sorted = prices.toSortedSet().toList()
val m = sorted.size
val get = { x: Int -> sorted.binarySearch(x) }
val left = IntArray(n) { -1 }
val right = IntArray(n) { -1 }
val bit = IntArray(m + 2) { -1 }
funupdate(i: Int, v: Int) {
var idx = i + 1while (idx < bit.size) {
bit[idx] = maxOf(bit[idx], v)
idx += idx and -idx
}
}
funquery(i: Int): Int {
var res = -1var idx = i + 1while (idx > 0) {
res = maxOf(res, bit[idx])
idx -= idx and -idx
}
return res
}
for (j in0 until n) {
left[j] = query(get(prices[j]) - 1)
update(get(prices[j]), profits[j])
}
bit.fill(-1)
for (j in n - 1 downTo 0) {
right[j] = query(m - get(prices[j]) - 2)
update(m - get(prices[j]) - 1, profits[j])
}
var ans = -1for (j in0 until n) {
if (left[j] != -1&& right[j] != -1) {
ans = maxOf(ans, left[j] + profits[j] + right[j])
}
}
return ans
}
}
classSolution:
defmaxProfit(self, prices: list[int], profits: list[int]) -> int:
n = len(prices)
sorted_prices = sorted(set(prices))
idx = {v: i for i, v in enumerate(sorted_prices)}
m = len(sorted_prices)
left = [-1] * n
right = [-1] * n
bit = [-1] * (m +2)
defupdate(i: int, v: int):
i +=1while i < len(bit):
bit[i] = max(bit[i], v)
i += i &-i
defquery(i: int) -> int:
res =-1 i +=1while i >0:
res = max(res, bit[i])
i -= i &-i
return res
for j in range(n):
left[j] = query(idx[prices[j]] -1)
update(idx[prices[j]], profits[j])
bit = [-1] * (m +2)
for j in range(n -1, -1, -1):
right[j] = query(m - idx[prices[j]] -2)
update(m - idx[prices[j]] -1, profits[j])
ans =-1for j in range(n):
if left[j] !=-1and right[j] !=-1:
ans = max(ans, left[j] + profits[j] + right[j])
return ans