124. Binary Tree Maximum Path Sum
leetcode hard
Task
Вам дан массив prices, где prices[i]— это цена акции в i-й день.
Найдите источник прибыли , которую можно получить, совершив не более двух транзакций. Важно : нельзя уча.
Важно: нельзя участвовать в нескольких транзакциях одновременно — нужно сначала продать , прежде чем покупать снова.
Пример:
Input: prices = [3,3,5,0,0,3,1,4] Output: 6алго
C# solution
matched/originalpublic class Solution {
public int MaxProfit(int[] prices) {
int length = prices.Length;
if (length <= 1)
return 0;
int leftMin = prices[0];
int rightMax = prices[length - 1];
int[] leftProfits = new int[length];
int[] rightProfits = new int[length + 1];
for (var l = 1; l < length; ++l) {
leftProfits[l] = Math.Max(leftProfits[l - 1], prices[l] - leftMin);
leftMin = Math.Min(leftMin, prices[l]);
int r = length - 1 - l;
rightProfits[r] =
Math.Max(rightProfits[r + 1], rightMax - prices[r]);
rightMax = Math.Max(rightMax, prices[r]);
}
var maxProfit = 0;
for (var i = 0; i < length; ++i)
maxProfit =
Math.Max(maxProfit, leftProfits[i] + rightProfits[i + 1]);
return maxProfit;
}
}C++ solution
auto-draft, review before submit#include <bits/stdc++.h>
using namespace std;
// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
public int MaxProfit(vector<int>& prices) {
int length = prices.size();
if (length <= 1)
return 0;
int leftMin = prices[0];
int rightMax = prices[length - 1];
vector<int>& leftProfits = new int[length];
vector<int>& rightProfits = new int[length + 1];
for (var l = 1; l < length; ++l) {
leftProfits[l] = max(leftProfits[l - 1], prices[l] - leftMin);
leftMin = min(leftMin, prices[l]);
int r = length - 1 - l;
rightProfits[r] =
max(rightProfits[r + 1], rightMax - prices[r]);
rightMax = max(rightMax, prices[r]);
}
var maxProfit = 0;
for (var i = 0; i < length; ++i)
maxProfit =
max(maxProfit, leftProfits[i] + rightProfits[i + 1]);
return maxProfit;
}
}Java solution
matched/originalclass Solution {
public int maxProfit(int[] prices) {
int length = prices.length;
if (length <= 1) return 0;
int leftMin = prices[0];
int rightMax = prices[length - 1];
int[] leftProfits = new int[length];
int[] rightProfits = new int[length + 1];
for (int l = 1; l < length; ++l) {
leftProfits[l] = Math.max(leftProfits[l - 1], prices[l] - leftMin);
leftMin = Math.min(leftMin, prices[l]);
int r = length - 1 - l;
rightProfits[r] = Math.max(
rightProfits[r + 1],
rightMax - prices[r]
);
rightMax = Math.max(rightMax, prices[r]);
}
int maxProfit = 0;
for (int i = 0; i < length; ++i) {
maxProfit = Math.max(
maxProfit,
leftProfits[i] + rightProfits[i + 1]
);
}
return maxProfit;
}
}JavaScript solution
matched/originalvar maxProfit = function (prices) {
if (prices.length <= 1) return 0;
let left_min = prices[0];
let right_max = prices[prices.length - 1];
let length = prices.length;
let left_profits = new Array(length).fill(0);
let right_profits = new Array(length + 1).fill(0);
for (let l = 1; l < length; ++l) {
left_profits[l] = Math.max(left_profits[l - 1], prices[l] - left_min);
left_min = Math.min(left_min, prices[l]);
let r = length - 1 - l;
right_profits[r] = Math.max(
right_profits[r + 1],
right_max - prices[r],
);
right_max = Math.max(right_max, prices[r]);
}
let max_profit = 0;
for (let i = 0; i < length; ++i) {
max_profit = Math.max(
max_profit,
left_profits[i] + right_profits[i + 1],
);
}
return max_profit;
};Python solution
matched/originalclass Solution(object):
def maxProfit(self, prices: List[int]) -> int:
if len(prices) <= 1:
return 0
left_min = prices[0]
right_max = prices[-1]
length = len(prices)
left_profits = [0] * length
# pad the right DP array with an additional zero for convenience.
right_profits = [0] * (length + 1)
# construct the bidirectional DP array
for l in range(1, length):
left_profits[l] = max(left_profits[l - 1], prices[l] - left_min)
left_min = min(left_min, prices[l])
r = length - 1 - l
right_profits[r] = max(right_profits[r + 1], right_max - prices[r])
right_max = max(right_max, prices[r])
max_profit = 0
for i in range(0, length):
max_profit = max(max_profit, left_profits[i] + right_profits[i + 1])
return max_profitGo solution
matched/originalfunc max(x int, y int) int {
if x > y {
return x
}
return y
}
func min(x int, y int) int {
if x > y {
return y
}
return x
}
func maxProfit(prices []int) int {
length := len(prices)
if length <= 1 {
return 0
}
leftMin := prices[0]
rightMax := prices[length-1]
leftProfits := make([]int, length)
rightProfits := make([]int, length+1)
for l := 1; l < length; l++ {
leftProfits[l] = max(leftProfits[l-1], prices[l]-leftMin)
leftMin = min(leftMin, prices[l])
r := length - 1 - l
rightProfits[r] = max(rightProfits[r+1], rightMax-prices[r])
rightMax = max(rightMax, prices[r])
}
maxProfit := 0
for i := 0; i < length; i++ {
maxProfit = max(maxProfit, leftProfits[i]+rightProfits[i+1])
}
return maxProfit
}Explanation
Algorithm
Пройдите массив слева направо, отслеживая минимальную цену и создавая массив leftProfits, где leftProfits[i]— максимальная прибыль от одной транзакции до дня i.
Пройдите по массиву справа налево, отслеживая дефекты цены и изменяя массив rightProfits, где rightProfits[i]— максимальная прибыль от одной транзакции со дня iдо конца.
Для каждого дня iпосчитайте сумму leftProfits[i] + rightProfits[i + 1]и найдите наибольшее значение этой суммы.
😎