5 kyu
尋找最大子陣列的和,包含空陣列。
從 index 0 為起點,每次都計算 start - end 的總和,比對是否較大。
end 如果到最後一位,start 遞增,end = start。
直到 start 到最後一位為止。
let start = 0
let end = 0
let max = -Infinity
let total
while loop start < arr.length - 1 如果 subarray 的起始到達陣列最尾,跳出循環
total = 0 每次循環都把總和重加
for loop start...end total += arr[?]
if(total > max) max = total
判斷 subarray 的頭尾
if end == arr.length - 1
start++
end = start
else
end++
var maxSequence = function (arr) {
if (arr.length === 0) return 0;
let allNegative = arr.filter(item => item > 0);
if (allNegative.length === 0) return 0;
let start = 0;
let end = 0;
let maxValue = -Infinity;
let sum;
while (start < arr.length - 1) {
sum = 0;
for (let i = start; i <= end; i++) {
sum += arr[i];
}
if (sum > maxValue) maxValue = sum;
if (end >= arr.length - 1) {
start++;
end = start;
} else {
end++;
}
}
return maxValue;
}
如果陣列長度為 0,直接返回 0。
filter 過濾元素為負數的,如果最後全負數也是返回 0。
宣告子陣列的 start 以及 end,while 迴圈在 start 跑到陣列最後位時會停止。
在每一次的迴圈都會把 sum 重新賦值為 0。
for loop 累加 start 到 end 的子陣列,取得總和與 maxValue 比對。
如果 sum > maxValue,則把 maxValue = sum。
判斷目前所在的 end 位置,如果到了陣列最後位,則 start 往前、end 提到 start 的下一個;否則繼續累加 end,直到最後返回 maxValue。
var maxSequence = function(arr){
var min = 0, ans = 0, i, sum = 0;
for (i = 0; i < arr.length; ++i) {
sum += arr[i];
min = Math.min(sum, min);
ans = Math.max(ans, sum - min);
}
return ans;
}
i 宣告在 for loop 之外;
紀錄最小值 min = 0, 紀錄解答(最大值) ans = 0, 紀錄每次的總和 sum = 0。
在每次的循環,sum 會累加 arr[i];
min 是追蹤當前位置之前的最小和;ans 紀錄最大的子陣列。
以陣列帶入 [-2, 1, -3, 4, -1, 2, 1, -5, 4]
為例:
i = 0
,sum = -2
,min = -2
,ans = 0
。i = 1
,sum = -1
,min = -2
,ans = 1
。i = 2
,sum = -4
,min = -4
,ans = 3
。i = 3
,sum = 0
,min = -4
,ans = 7
。i = 4
,sum = -1
,min = -4
,ans = 7
。i = 5
,sum = 1
,min = -4
,ans = 7
。i = 6
,sum = 2
,min = -4
,ans = 7
。i = 7
,sum = -3
,min = -4
,ans = 7
。i = 8
,sum = 1
,min = -4
,ans = 7
。-4 的 min 組成是子陣列 [-2, 1, -3]
。
sum 表示的就是累加到當前的子陣列,min 本身也是從 0 累加的子陣列。sum - min
是為了確保目前的 ans 所記錄的是最大的子陣列。
假設 index 0 - 3 為 min,sum 已經計算到 index 0 - 6;
sum - min 之後,就是在比對 index 4 - 6 是否存在比 ans 更大的可能。
這題的最佳解燒了我的腦袋,看了討論區貌似是數學相關的巧思。