• Time:O(n)
• Space:O(1)

## C++

``````class Solution {
public:
int maxSubArray(vector<int>& nums) {
int ans = INT_MIN;
int sum = 0;

for (const int num : nums) {
sum += num;
ans = max(ans, sum);
sum = max(sum, 0);
}

return ans;
}
};
``````

## JAVA

``````class Solution {
public int maxSubArray(int[] nums) {
int ans = Integer.MIN_VALUE;
int sum = 0;

for (final int num : nums) {
sum += num;
ans = Math.max(ans, sum);
sum = Math.max(sum, 0);
}

return ans;
}
}
``````

## Python

``````class Solution:
def maxSubArray(self, nums: List[int]) -> int:
ans = -math.inf
summ = 0

for num in nums:
summ += num
ans = max(ans, summ)
summ = max(summ, 0)

return ans
``````

## Approach 2: Divide and Conquer

• Time:O(n\log n)
• Space:O(\log n)

## C++

``````struct T {
int left;   // sum of the subarray w/ max sum (starting from the first num)
int right;  // sum of the subarray w/ max sum (ending at the the last num)
int mid;    // sum of the subarray w/ max sum
int sum;    // sum of the whole array
};

class Solution {
public:
int maxSubArray(vector<int>& nums) {
return divideAndConquer(nums, 0, nums.size() - 1).mid;
}

private:
T divideAndConquer(const vector<int>& nums, int l, int r) {
if (l == r)
return {nums[l], nums[l], nums[l], nums[l]};

const int m = (l + r) / 2;
const T t1 = divideAndConquer(nums, l, m);
const T t2 = divideAndConquer(nums, m + 1, r);

const int left = max(t1.left, t1.sum + t2.left);
const int right = max(t1.right + t2.sum, t2.right);
const int mid = max({t1.right + t2.left, t1.mid, t2.mid});
const int sum = t1.sum + t2.sum;
return {left, right, mid, sum};
}
};
``````

## JAVA

``````class T {
public int left;  // sum of the subarray w/ max sum (starting from the first num)
public int right; // sum of the subarray w/ max sum (ending at the the last num)
public int mid;   // sum of the subarray w/ max sum
public int sum;   // sum of the whole array
public T(int left, int right, int mid, int sum) {
this.left = left;
this.right = right;
this.mid = mid;
this.sum = sum;
}
}

class Solution {
public int maxSubArray(int[] nums) {
return divideAndConquer(nums, 0, nums.length - 1).mid;
}

private T divideAndConquer(int[] nums, int l, int r) {
if (l == r)
return new T(nums[l], nums[l], nums[l], nums[l]);

final int m = (l + r) / 2;
final T t1 = divideAndConquer(nums, l, m);
final T t2 = divideAndConquer(nums, m + 1, r);

final int left = Math.max(t1.left, t1.sum + t2.left);
final int right = Math.max(t1.right + t2.sum, t2.right);
final int mid = Math.max(t1.right + t2.left, Math.max(t1.mid, t2.mid));
final int sum = t1.sum + t2.sum;
return new T(left, right, mid, sum);
}
}
``````

## Python

``````class Solution:
def maxSubArray(self, nums: List[int]) -> int:
def divideAndConquer(l: int, r: int) -> Tuple[int, int, int, int]:
if l == r:
return nums[l], nums[l], nums[l], nums[l]

m = (l + r) // 2
t1 = divideAndConquer(l, m)
t2 = divideAndConquer(m + 1, r)

left = max(t1[0], t1[3] + t2[0])
right = max(t1[1] + t2[3], t2[1])
mid = max(t1[1] + t2[0], max(t1[2], t2[2]))
summ = t1[3] + t2[3]
return left, right, mid, summ

return divideAndConquer(0, len(nums) - 1)[2]
``````

• Time:O(n)
• Space:O(n)

## C++

``````class Solution {
public:
int maxSubArray(vector<int>& nums) {
// dp[i] := max sum subarray ending w/ nums[i]
vector<int> dp(nums.size());

for (int i = 0; i < nums.size(); ++i)
if (i > 0 && dp[i - 1] > 0)
dp[i] = dp[i - 1] + nums[i];
else
dp[i] = nums[i];

return *max_element(begin(dp), end(dp));
}
};
``````

## JAVA

``````class Solution {
public int maxSubArray(int[] nums) {
// dp[i] := max sum subarray ending w/ nums[i]
int[] dp = new int[nums.length];

for (int i = 0; i < nums.length; ++i)
if (i > 0 && dp[i - 1] > 0)
dp[i] = dp[i - 1] + nums[i];
else
dp[i] = nums[i];

return Arrays.stream(dp).max().getAsInt();
}
}
``````

## Python

``````class Solution:
def maxSubArray(self, nums: List[int]) -> int:
# dp[i] := max sum subarray ending w/ nums[i]
dp = [0] * len(nums)

for i, num in enumerate(nums):
if i > 0 and dp[i - 1] > 0:
dp[i] = dp[i - 1] + num
else:
dp[i] = num

return max(dp)
``````