Problem Statement:
Given an integer array nums
, find the subarray with the largest sum, and return its sum.
Example 1: Input: nums = [-2,1,-3,4,-1,2,1,-5,4] Output: 6 Explanation: The subarray [4,-1,2,1] has the largest sum 6.
Example 2: Input: nums = [1] Output: 1 Explanation: The subarray [1] has the largest sum 1.
Example 3: Input: nums = [5,4,-1,7,8] Output: 23 Explanation: The subarray [5,4,-1,7,8] has the largest sum 23.
Constraints:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
Solution:
1. Recursion and Memoization:
class Solution {
public int maxSubArray(int[] nums) {
// We use an array to keep track of the maximum sum found so far.
int[] maxSum = new int[]{Integer.MIN_VALUE};
int[] memo = new int[nums.length];
Arrays.fill(memo, -1);
// Start the recursion from the last index.
maxSubArrayUtil(nums, nums.length - 1, maxSum, memo);
return maxSum[0];
}
private int maxSubArrayUtil(int[] nums, int idx, int[] maxSum, int[] memo) {
// Base case: If idx is out of bounds, return 0 (end of recursion).
if (idx < 0) {
return 0;
}
if(memo[idx] != -1){
return memo[idx];
}
// Recursive step: Get the maximum subarray sum ending at the previous index.
int currentMax = maxSubArrayUtil(nums, idx - 1, maxSum, memo);
// Include the current element to the previous subarray or start a new subarray with the current element.
int sumIncludingCurrent = Math.max(nums[idx], currentMax + nums[idx]);
// Update the global maximum sum if the current subarray sum is larger.
maxSum[0] = Math.max(maxSum[0], sumIncludingCurrent);
// Return the maximum sum ending at the current index.
return memo[idx] = sumIncludingCurrent;
}
}
2. Tabulation
class Solution {
public int maxSubArray(int[] nums) {
// We use an array to keep track of the maximum sum found so far.
int n = nums.length;
int[] dp = new int[n + 1];
//base case
dp[0] = nums[0];
int maxSum = dp[0];
for(int i = 1; i < n; i++){
int currentMax = dp[i - 1];
dp[i] = Math.max(nums[i], currentMax + nums[i]);
maxSum = Math.max(maxSum, dp[i]);
}
return maxSum;
}
}
3. Space Optimized:
class Solution {
public int maxSubArray(int[] nums) {
// We use an array to keep track of the maximum sum found so far.
int n = nums.length;
int prev = nums[0];
int maxSum = prev;
for(int i = 1; i < n; i++){
int curr = Math.max(nums[i], prev + nums[i]);
maxSum = Math.max(maxSum, curr);
prev = curr;
}
return maxSum;
}
}