AfterAcademy Tech
•
16 Oct 2019

Difficulty Level: Hard
Asked in: Facebook, Microsoft, Amazon, Goldman Sachs
Problem Description: You are given an array A[] with n elements. You need to find the maximum sum of a subarray among all subarrays of that array. A subarray of array A[] of length n is a contiguous segment from A[i] through A[j] where 0<= i <= j <= n. Some properties of this problem are:
For Example :
Input: A[] = {-5, 8, 9, -6, 10, -15, 3}
Output: 21, the subarray {8, 9, -6, 10} has the maximum sum among all subarrays
Input: A[] = { -4, -7, -1, 5,-2}
Output: 4, the subarray {-1, 5} has the maximum sum
Possible follow-up questions to ask the interviewer:-
We will be discussing five solutions for this problem:-
We would use nested loops to determine all the possible subarray sums and return the maximum among them. For this, we generate all (i, j): i <= j pairs and calculate the sum between.
Pseudo-Code
int maxSubarraySum ( int A [] , int n)
{
int max_sum = 0
for(i = 0 to n-1)
{
for(j = i to n-1)
{
int sum = 0
for(k = i to j)
sum = sum + A[k]
if(sum > max_sum)
max_sum = sum
}
}
return max_sum
}
Complexity Analysis
Time Complexity: O(n^3) (Why?)
Space Complexity: O(1)
Critical ideas to think!
This is the optimized version of the above approach. The idea is to start at all positions in the array and calculate running sums. The outer loop picks the beginning element, the inner loop finds the maximum possible sum with the first element picked by the outer loop and compares this maximum with the overall maximum.
int max_Subarray_Sum ( int A[] , int n)
{
int max_sum = 0
for ( i = 0 to n-1)
{
sum=0
for( j = i to n-1)
{
sum = sum + A[j]
if (sum > max_sum)
max_sum = sum
}
}
retun max_sum
}
Complexity Analysis
Time Complexity: O(n^2) (Why?)
Space Complexity: O(1)
Critical ideas to think!
You could divide the array into two equal parts and then recursively find the maximum subarray sum of the left part and the right part. But what if the actual subarray with maximum sum is formed of some elements from the left and some elements from the right? Think!
The sub-array we’re looking for can be in only one of three places:
You could very easily find a cross-sum of elements from the left side and right side which cross the mid-element in linear time.
Solution Steps
4. Return the maximum among (left, right, cross-sum)
Pseudo-Code
// The original values would be low = 0 and high = n-1
int maxSubarraySum (int A[], int low, int high)
{
if (low == high)
return A[low]
else
{
int mid = low + (high - low)/2
int left_sum = maxSubarraySum (A, low, mid)
int right_sum = maxSubarraySum (A, mid+1, high)
int crossing_Sum = maxCrossingSum(A, low, mid, high)
return max (left_sum, right_sum, crossing_Sum)
}
}
int maxCrossingSum(int A[], int l, int mid, int r)
{
int sum = 0
int lsum = INT_MIN
for(i = mid to l)
{
sum = sum + A[i]
If (sum > lsum)
lsum = sum
}
sum = 0
int rsum = INT_MIN
for(i = mid+1 to r)
{
sum = sum + A[i]
If (sum > rsum)
rsum = sum
}
return (lsum + rsum)
}
Complexity Analysis
Time Complexity: The recurrence relation formed for this Divide and Conquer approach is similar to the recurrence relation of Merge Sort
T(n) = 2T(n/2) + O(n) = O(nlogn)
Space Complexity = O(logn), stack space by recursive calls
Critical ideas to think!
We can store the maximum subarray sum ending at a particular index in an auxiliary array and then traverse the auxiliary array to find the maximum subarray sum.
Solution Steps
4. Return the maximum element present in max_ending_here array
Pseudo-Code
int maxSubarraySum(int A[], int n)
{
int max_ending_here[n]
max_ending_here[0] = A[0]
for ( i = 1 to n-1 )
{
if ( A[i] + max_ending_here[i-1] > 0 )
max_ending_here[i] = A[i] + max_ending_here[i-1]
else
max_ending_here[i] = A[i]
}
int ans = 0
for( i = 0 to n-1 )
ans = max(ans, max_ending_here[i])
return ans
}
Complexity Analysis
Time Complexity: Traversing array A + Traversing the auxiliary array
= O(n) + O(n) = O(n)
Space Complexity = O(n), for storing the auxiliary array
Critical ideas to think!
The idea followed in Kadane’s algorithm is to maintain the maximum possible sum of a subarray ending at an index without needing to store the numbers in an auxiliary array. It is an improvement in the previous dynamic programming approach optimizing the space complexity.
Solution Steps
Pseudo-Code
int maxSubarraySum(int A[], int n)
{
int max_so_far = 0
int max_ending_here = 0
for ( i = 0 to n-1 )
{
max_ending_here += A[i]
if( max_ending_here < 0 )
max_ending_here = 0
max_so_far = max(max_so_far, max_ending_here)
}
return max_so_far
}
Complexity Analysis
Notice that each element has been visited only once.
Time Complexity = O(n)
Space Complexity = O(1)
Critical ideas to think!

Happy Coding! Enjoy Algorithms!
AfterAcademy Tech
Given a non-empty binary tree, find maximum path sum. For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along with the parent-child connections.

AfterAcademy Tech
Given an array A[] of n integer elements, find the length of the longest subarray with sum equals to 0.

AfterAcademy Tech
Given an array of integers arr[] and a target number k, write a program to find all unique combinations in arr[] such that the sum of all integers in the combination is equal to k. This famous backtracking problem has previously been asked in Adobe, Amazon, Facebook.

AfterAcademy Tech
write a program to find three numbers whose product is maximum and output the maximum product. This is a basic mathematical problem and requires logical skill to solve.
