ÐакÑималÑний пÑдмаÑив
Ðа вÑ
Ð¾Ð´Ñ Ð¼Ð°Ñив ÑиÑел, напÑиклад arr = [1, -2, 3, 4, -9, 6].
ÐавданнÑ: знайÑи непеÑеÑвний пÑдмаÑив arr з макÑималÑÐ½Ð¾Ñ ÑÑÐ¼Ð¾Ñ ÐµÐ»ÐµÐ¼ÐµÐ½ÑÑв.
ÐапиÑаÑи ÑÑнкÑÑÑ getMaxSubSum(arr) Ñка повеÑÑÐ°Ñ ÑÐ°ÐºÑ ÑÑмÑ.
ÐапÑиклад:
getMaxSubSum([-1, 2, 3, -9]) == 5 (the sum of highlighted items)
getMaxSubSum([2, -1, 2, 3, -9]) == 6
getMaxSubSum([-1, 2, 3, -9, 11]) == 11
getMaxSubSum([-2, -1, 1, 2]) == 3
getMaxSubSum([100, -9, 2, -3, 5]) == 100
getMaxSubSum([1, 2, 3]) == 6 (take all)
ЯкÑо вÑÑ ÐµÐ»ÐµÐ¼ÐµÐ½Ñи менÑÑ Ð½ÑлÑ, нÑÑого не беÑемо, Ñе ознаÑаÑ, Ñо пÑдмаÑив пÑÑÑий, а ÑÑма ÑÑвна нÑлÑ:
getMaxSubSum([-1, -2, -3]) = 0
ÐÑÐ´Ñ Ð»Ð°Ñка, подÑмайÑе над Ñвидким ÑÑÑеннÑм: O(n2) або навÑÑÑ Ð½Ð°Ð´ ÑÑÑеннÑм O(n), ÑкÑо зможеÑе.
ÐовÑлÑне ÑÑÑеннÑ
Ðи можемо поÑÐ°Ñ ÑваÑи вÑÑ Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ñ Ð¿ÑдÑÑми.
ÐайпÑоÑÑÑÑий ÑлÑÑ â Ñе поÑÐ°Ñ ÑваÑи ÑÑми вÑÑÑ Ð¿ÑдмаÑивÑв, поÑинаÑÑи з кожного елеменÑа.
ÐапÑиклад, Ð´Ð»Ñ [-1, 2, 3, -9, 11]:
// ÐоÑинаÑмо з -1:
-1
-1 + 2
-1 + 2 + 3
-1 + 2 + 3 + (-9)
-1 + 2 + 3 + (-9) + 11
// ÐоÑинаÑмо з 2:
2
2 + 3
2 + 3 + (-9)
2 + 3 + (-9) + 11
// ÐоÑинаÑмо з 3:
3
3 + (-9)
3 + (-9) + 11
// ÐоÑинаÑмо з -9
-9
-9 + 11
// ÐоÑинаÑмо з 11
11
ÐиÑÑÑÐµÐ½Ð½Ñ Ð¿Ð¾ÑÑебÑÑ Ð²Ð¸ÐºÐ¾ÑиÑÑÐ°Ð½Ð½Ñ ÑиклÑв: зовнÑÑний Ñикл пÑÐ¾Ñ Ð¾Ð´Ð¸ÑÑ Ð¿Ð¾ елеменÑÐ°Ñ Ð¼Ð°ÑивÑ, а внÑÑÑÑÑнÑй ÑÐ°Ñ ÑÑ Ð¿ÑдÑÑÐ¼Ñ Ð¿Ð¾ÑинаÑÑи з поÑоÑного елеменÑÑ.
function getMaxSubSum(arr) {
let maxSum = 0; // ÑкÑо елеменÑи вÑдÑÑÑÐ½Ñ - повеÑÑаÑмо 0
for (let i = 0; i < arr.length; i++) {
let sumFixedStart = 0;
for (let j = i; j < arr.length; j++) {
sumFixedStart += arr[j];
maxSum = Math.max(maxSum, sumFixedStart);
}
}
return maxSum;
}
alert( getMaxSubSum([-1, 2, 3, -9]) ); // 5
alert( getMaxSubSum([-1, 2, 3, -9, 11]) ); // 11
alert( getMaxSubSum([-2, -1, 1, 2]) ); // 3
alert( getMaxSubSum([1, 2, 3]) ); // 6
alert( getMaxSubSum([100, -9, 2, -3, 5]) ); // 100
Таке ÑÑÑÐµÐ½Ð½Ñ Ð¼Ð°Ñ Ð¾ÑÑÐ½ÐºÑ ÑаÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ O(n2). ÐнакÑе кажÑÑи, ÑкÑо ми збÑлÑÑимо ÑозмÑÑ Ð¼Ð°ÑÐ¸Ð²Ñ Ð²Ð´Ð²ÑÑÑ, алгоÑиÑм бÑде виконÑваÑиÑÑ Ð² 4 Ñази довÑе.
ÐÐ»Ñ Ð²ÐµÐ»Ð¸ÐºÐ¸Ñ Ð¼Ð°ÑивÑв (1000, 10000 або бÑлÑÑе елеменÑÑв) подÑÐ±Ð½Ñ Ð°Ð»Ð³Ð¾ÑиÑми можÑÑÑ Ð¿ÑизводиÑи до ÑеÑÐ¹Ð¾Ð·Ð½Ð¸Ñ âпÑигалÑмÑванÑâ в ÑобоÑÑ.
Швидке ÑÑÑеннÑ
ÐÑойдемоÑÑ Ð¿Ð¾ маÑÐ¸Ð²Ñ Ñ Ð² пÑоÑеÑÑ Ð±Ñдемо накопиÑÑваÑи пÑомÑÐ¶Ð½Ñ ÑÑÐ¼Ñ ÐµÐ»ÐµÐ¼ÐµÐ½ÑÑв в змÑннÑй s. ЯкÑо в певний Ð¼Ð¾Ð¼ÐµÐ½Ñ s ÑÑане менÑÐ¾Ñ Ð·Ð° 0, пÑиÑвоÑмо s=0. ÐакÑималÑне знаÑÐµÐ½Ð½Ñ Ð· ÑÑÑÑ
s Ñ Ð±Ñде вÑдповÑддÑ.
ЯкÑо поÑÑÐ½ÐµÐ½Ð½Ñ Ð½Ðµ дÑже зÑозÑмÑле, подивÑÑÑÑÑ, бÑÐ´Ñ Ð»Ð°Ñка, на код â вÑн доÑиÑÑ Ð»Ð°ÐºÐ¾Ð½ÑÑний:
function getMaxSubSum(arr) {
let maxSum = 0;
let partialSum = 0;
for (let item of arr) { // for each item of arr
partialSum += item; // add it to partialSum
maxSum = Math.max(maxSum, partialSum); // remember the maximum
if (partialSum < 0) partialSum = 0; // zero if negative
}
return maxSum;
}
alert( getMaxSubSum([-1, 2, 3, -9]) ); // 5
alert( getMaxSubSum([-1, 2, 3, -9, 11]) ); // 11
alert( getMaxSubSum([-2, -1, 1, 2]) ); // 3
alert( getMaxSubSum([100, -9, 2, -3, 5]) ); // 100
alert( getMaxSubSum([1, 2, 3]) ); // 6
alert( getMaxSubSum([-1, -2, -3]) ); // 0
Цей алгоÑиÑм поÑÑебÑÑ ÑÑвно один пÑÐ¾Ñ Ñд по маÑивÑ, його оÑÑноÑний ÑÐ°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ â O(n).
Ðи можеÑе дÑзнаÑиÑÑ Ð±ÑлÑÑе пÑо Ñей алгоÑиÑм ÑÑÑ: Maximum subarray problem. ЯкÑо доÑÑ Ð½Ðµ зÑозÑмÑло, Ñк Ñе пÑаÑÑÑ, бÑÐ´Ñ Ð»Ð°Ñка, подивÑÑÑÑÑ Ð°Ð»Ð³Ð¾ÑиÑм Ñ Ð¿ÑÐ¸ÐºÐ»Ð°Ð´Ð°Ñ Ð²Ð¸Ñе, Ñе бÑде кÑаÑе за бÑдÑ-ÑÐºÑ Ñлова.
ÐÑдкÑиÑи ÑÑÑÐµÐ½Ð½Ñ Ñз ÑеÑÑами в пÑÑоÑниÑÑ.