Problem
Given an integer array nums
, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.
Examples
Example 1:
|
|
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.
Solution
There are multiple solutions possible to this problem:
- Brute force - O(n^3)
- Kadane’s algorithm - O(n)
- Dynamic Programming - O(n), Space complexity - O(n)
- Divide and Conquer
Video explanation
Here is the video explaining different methods including naive, divide and conquer and Kadane’s algorithm in detail. Please check it out:
Method 1 - Brute Force
The naive approach involves computing the sum of every possible subarray in the array and keeping track of the maximum sum encountered. This approach uses three nested loops:
- Outer Loop: Iterate over each starting point of the subarray.
- Middle Loop: Iterate over each ending point of the subarray, starting from the current starting point.
- Inner Loop: Calculate the sum of the subarray defined by the outer and middle loop boundaries.
Pseudocode
|
|
Complexity
- ⏰ Time complexity:
O(n^3)
because of the three nested loops. - 🧺 Space complexity:
O(1)
since no additional space is used outside of a few variables.
Method 2 - Optimize on innermost loop
If we look at the previous solution, we don’t need innermost loop that recalculates the sum for each subarray from scratch. Instead, we build on the sum of previous subarrays, achieving a time complexity of O(n^2)
.
Pseudocode
|
|
Complexity
- ⏰ Time complexity:
O(n^2)
because of the two nested loops. - 🧺 Space complexity:
O(1)
as we use a constant amount of extra space.
Method 3 - Kadane’s Algorithm 🏆
Kadane’s Algorithm for Maximum Subarray Sum
Complexity
- ⏰ Time complexity:
O(n)
- 🧺 Space complexity:
O(1)
Method 4 - Using Bottom-up DP
We can use Dynamic programming (DP) to solve this problem. The approach involves finding the maximum subarray sum ending at each index and using these results to construct the solution for the subsequent indices.
Algorithm
- Subproblems: Define
dp[i]
to be the maximum subarray sum ending at indexi
in the array. The - Recurrence relation:
dp[i] = max(dp[i-1] + arr[i], arr[i])
- This means that the maximum sum subarray ending at
i
is either:- The maximum sum subarray ending at
i-1
plus the element ati
- The element at
i
itself (in case the maximum subarray sum ending ati-1
is negative)
- The maximum sum subarray ending at
- This means that the maximum sum subarray ending at
- Base case: Generally, the DP solution starts with a base case. In this problem, the base case is:
dp[0] = arr[0]
- Iterate and Fill the Table: Now fill the table from
i = 1 to n
- Reconstruct the Solution: While the previous step can give you the maximum subarray sum up to every index, the overall maximum subarray sum can be found by iterating through the
dp
array.maxSubarraySum = max(dp[0], dp[1], ..., dp[n-1])
- OR we can use
max
variable to track the max indp
array.
- OR we can use
Code
|
|
Complexity
- ⏰ Time complexity:
O(n)
- 🧺 Space complexity:
O(n)
Method 4 - Divide and Conquer
We can also use Divide and Conquer:
- Task is to find out subarray which has the largest sum. So we need to find out the 2 indexes (
left
index andright
index) between which the sum is maximum. - Divide array into left half and right half.
- Conquer by recursively find maximum subarray sum for the left and right.
- Combine or merge the following possibilities as final result:
- Maximum subarray sum in the left half (Left index and right index both are in left half of the array).
- Maximum subarray sum in the right half. (Left index and right index both are in right half of the array).
- Maximum subarray sum that crosses the dividing line. (Left index in the and left half of the array and right index in right half of the array).
Code
|
|
Complexity
- ⏰ Time complexity:
O(n log n)
- 🧺 Space complexity:
O(log n)