/* Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.
Example:
Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
Follow up:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle. */
/**
* @param {number[]} nums
* @return {number}
*/
//first try
var maxSubArray = function (nums) {
const len = nums.length
let curr = nums[0],
highestSoFar = curr,
next
for (let i = 1; i < len; i++) {
const element = nums[i]
next = curr + nums[i]
if (next > highestSoFar) {
highestSoFar = next
}
if (next > curr && element > next) {
next = element
}
if (element > highestSoFar) {
highestSoFar = element
}
curr = next
}
return highestSoFar
}
//Refactored. If element by itself is greater than the sum, dump the sum and use that element to "reset" the sum. And keep track of maxSum.
//Time - O(n), space - O(1)
var maxSubArray = function (nums) {
const len = nums.length
let sum = nums[0],
maxSum = sum
for (let i = 1; i < len; i++) {
const element = nums[i]
sum = Math.max(element, sum + nums[i])
maxSum = Math.max(maxSum, sum)
}
return maxSum
}
//using recursion. Don't u/stand well
function crossSubarray(array, left, middle, right) {
var leftSum = -Infinity
var rightSum = -Infinity
var sum = 0
for (var i = middle; i >= left; i--) {
leftSum = Math.max(sum + array[i], leftSum)
sum += array[i]
}
sum = 0
for (var i = middle + 1; i < right; i++) {
rightSum = Math.max(sum + array[i], rightSum)
sum += array[i]
}
return leftSum + rightSum
}
function maxSubarrayPartitioner(array, left, right) {
if (right - left <= 1) {
return array[left]
}
var middle = Math.floor((left + right) / 2)
var leftSum = maxSubarrayPartitioner(array, left, middle)
var rightSum = maxSubarrayPartitioner(array, middle, right)
var crossSum = crossSubarray(array, left, middle, right)
return Math.max(crossSum, leftSum, rightSum)
}
function maxSubarraydivideAndConquer(array) {
return maxSubarrayPartitioner(array, 0, array.length)
}
//Test cases
console.log(maxSubarraydivideAndConquer([-2, 1, -3, 4, -1, 2, 1, -5, 4])) //6
console.log(maxSubArray([-2, 1, -3, 4, -1, 2, 1, -5, 4])) //6
console.log(maxSubArray([-2, -1])) //-1
console.log(maxSubArray([8, -19, 5, -4, 20])) //21
console.log(maxSubArray([3, 2, -3, -1, 1, -3, 1, -1])) //5