Given an array of positive numbers, find the maximum sum of a subsequence such that no two numbers in the subsequence should be adjacent in the array.
Examples:
Input: arr[] = {5, 5, 10, 100, 10, 5} Output: 110 Explanation: Pick the subsequence {5, 100, 5}. The sum is 110 and no two elements are adjacent. This is the highest possible sum.
Input: arr[] = {3, 2, 7, 10} Output: 13 Explanation: The subsequence is {3, 10}. This gives the highest possible sum = 13.
Input: arr[] = {3, 2, 5, 10, 7} Output: 15 Explanation: Pick the subsequence {3, 5, 7}. The sum is 15.
[Naive Approach] Using Recursion- O(2^n) Time and O(n) Space
The idea is to explore all the possibilities for each element using Recursion. We can start from the last element and for each element, we have two choices:
Pick the current element and skip the element just before it.
Skip the current element and move to the element just before it.
So, the recurrence relation will be:
maxSumRec(n) = max(arr[n - 1] + maxSumRec(n - 2), maxSumRec(n - 1)), where maxSumRec(n) returns the maximum sum if n elements are left.
C++
// C++ Program to find maximum sum with no two adjacent using Recursion#include<iostream>#include<vector>usingnamespacestd;// Calculate the maximum Sum value recursivelyintmaxSumRec(vector<int>&arr,intn){// If no elements are left, return 0.if(n<=0)return0;// If only 1 element is left, pick it. if(n==1)returnarr[0];// Two Choices: pick the nth element and do not pick the nth element intpick=arr[n-1]+maxSumRec(arr,n-2);intnotPick=maxSumRec(arr,n-1);// Return the max of two choicesreturnmax(pick,notPick);}// Function to calculate the maximum Sum valueintmaxSum(vector<int>&arr){intn=arr.size();// Call the recursive function for n elementsreturnmaxSumRec(arr,n);}intmain(){vector<int>arr={6,7,1,3,8,2,4};cout<<maxSum(arr);return0;}
C
// C Program to find maximum sum with no two adjacent using Recursion#include<stdio.h>// Function to calculate the maximum Sum valueintmaxSum(int*arr,intn){// If no elements are left, return 0.if(n<=0)return0;// If only 1 element is left, pick it. if(n==1)returnarr[0];// Two Choices: pick the nth element and do not pick the nth element intpick=arr[n-1]+maxSum(arr,n-2);intnotPick=maxSum(arr,n-1);// Return the max of two choicesreturn(pick>notPick)?pick:notPick;}intmain(){intarr[]={6,7,1,3,8,2,4};intn=sizeof(arr)/sizeof(arr[0]);printf("%d\n",maxSum(arr,n));return0;}
Java
// Java Program to find maximum sum with no two adjacent using RecursionclassGfG{// Calculate the maximum Sum value recursivelystaticintmaxSumRec(int[]arr,intn){// If no elements are left, return 0.if(n<=0)return0;// If only 1 element is left, pick it. if(n==1)returnarr[0];// Two Choices: pick the nth element and do not pick the nth element intpick=arr[n-1]+maxSumRec(arr,n-2);intnotPick=maxSumRec(arr,n-1);// Return the max of two choicesreturnMath.max(pick,notPick);}// Function to calculate the maximum Sum valuestaticintmaxSum(int[]arr){intn=arr.length;// Call the recursive function for n elementsreturnmaxSumRec(arr,n);}publicstaticvoidmain(String[]args){int[]arr={6,7,1,3,8,2,4};System.out.println(maxSum(arr));}}
Python
# Python Program to find maximum sum with no two adjacent using Recursion# Calculate the maximum Sum value recursivelydefmaxSumRec(arr,n):# If no elements are left, return 0.ifn<=0:return0# If only 1 element is left, pick it. ifn==1:returnarr[0]# Two Choices: pick the nth element and do not pick the nth element pick=arr[n-1]+maxSumRec(arr,n-2)notPick=maxSumRec(arr,n-1)# Return the max of two choicesreturnmax(pick,notPick)# Function to calculate the maximum Sum valuedefmaxSum(arr):n=len(arr)# Call the recursive function for n elementsreturnmaxSumRec(arr,n)if__name__=="__main__":arr=[6,7,1,3,8,2,4]print(maxSum(arr))
C#
// C# Program to find maximum sum with no two adjacent using RecursionusingSystem;classGfG{// Calculate the maximum Sum value recursivelystaticintmaxSumRec(int[]arr,intn){// If no elements are left, return 0.if(n<=0)return0;// If only 1 element is left, pick it. if(n==1)returnarr[0];// Two Choices: pick the nth element and do not pick the nth element intpick=arr[n-1]+maxSumRec(arr,n-2);intnotPick=maxSumRec(arr,n-1);// Return the max of two choicesreturnMath.Max(pick,notPick);}// Function to calculate the maximum Sum valuestaticintmaxSum(int[]arr){intn=arr.Length;// Call the recursive function for n elementsreturnmaxSumRec(arr,n);}staticvoidMain(){int[]arr={6,7,1,3,8,2,4};Console.WriteLine(maxSum(arr));}}
JavaScript
// JavaScript Program to find maximum sum with no two adjacent using Recursion// Calculate the maximum Sum value recursivelyfunctionmaxSumRec(arr,n){// If no elements are left, return 0.if(n<=0)return0;// If only 1 element is left, pick it. if(n===1)returnarr[0];// Two Choices: pick the nth element and do not pick the nth element letpick=arr[n-1]+maxSumRec(arr,n-2);letnotPick=maxSumRec(arr,n-1);// Return the max of two choicesreturnMath.max(pick,notPick);}// Function to calculate the maximum Sum valuefunctionmaxSum(arr){letn=arr.length;// Call the recursive function for n elementsreturnmaxSumRec(arr,n);}letarr=[6,7,1,3,8,2,4];console.log(maxSum(arr));
Output
19
Time Complexity: O(2n). Every element has 2 choices to pick and not pick. Auxiliary Space: O(n).For recursion stack space
[Better Approach] Using Memoization - O(n) Time and O(n) Space
We can optimize this solution using a memo array of size (n + 1), such that memo[i] represents the maximum value that can be collected from first i elements. Please note that there is only one parameter that changes in recursion and the range of this parameter is from 0 to n.
C++
// C++ Program to find maximum sum with no two adjacent#include<iostream>#include<vector>usingnamespacestd;intmaxSumRec(vector<int>&arr,intn,vector<int>&memo){if(n<=0)return0;if(n==1)returnarr[0];// Check if the result is already computedif(memo[n]!=-1)returnmemo[n];intpick=arr[n-1]+maxSumRec(arr,n-2,memo);intnotPick=maxSumRec(arr,n-1,memo);// Store the max of two choices in the memo array and return itmemo[n]=max(pick,notPick);returnmemo[n];}intmaxSum(vector<int>&arr){intn=arr.size();// Initialize memo array with -1vector<int>memo(n+1,-1);returnmaxSumRec(arr,n,memo);}intmain(){vector<int>arr={6,7,1,3,8,2,4};cout<<maxSum(arr);return0;}
C
// C Program to find maximum sum with no two adjacent#include<stdio.h>#include<stdlib.h>intmaxSumRec(constint*arr,intn,int*memo){if(n<=0)return0;if(n==1)returnarr[0];// Check if the result is already computedif(memo[n]!=-1)returnmemo[n];intpick=arr[n-1]+maxSumRec(arr,n-2,memo);intnotPick=maxSumRec(arr,n-1,memo);// Store the max of two choices in the memo array and return itmemo[n]=(pick>notPick)?pick:notPick;returnmemo[n];}intmaxSum(int*arr,intn){// Initialize memo array with -1intmemo[n+1];for(inti=0;i<=n;++i){memo[i]=-1;}intresult=maxSumRec(arr,n,memo);returnresult;}intmain(){intarr[]={6,7,1,3,8,2,4};intn=sizeof(arr)/sizeof(arr[0]);printf("%d\n",maxSum(arr,n));return0;}
Java
// Java Program to find maximum sum with no two adjacentimportjava.util.Arrays;classGfG{staticintmaxSumRec(int[]arr,intn,int[]memo){if(n<=0)return0;if(n==1)returnarr[0];// Check if the result is already computedif(memo[n]!=-1)returnmemo[n];intpick=arr[n-1]+maxSumRec(arr,n-2,memo);intnotPick=maxSumRec(arr,n-1,memo);// Store the max of two choices in the memo array and return itmemo[n]=Math.max(pick,notPick);returnmemo[n];}// Function to calculate the maximum Sum valuestaticintmaxSum(int[]arr){intn=arr.length;// Initialize memo array with -1int[]memo=newint[n+1];Arrays.fill(memo,-1);returnmaxSumRec(arr,n,memo);}publicstaticvoidmain(String[]args){int[]arr={6,7,1,3,8,2,4};System.out.println(maxSum(arr));}}
Python
# Python Program to find maximum sum with no two adjacentdefmaxSumRec(arr,n,memo):ifn<=0:return0ifn==1:returnarr[0]# Check if the result is already computedifmemo[n]!=-1:returnmemo[n]pick=arr[n-1]+maxSumRec(arr,n-2,memo)notPick=maxSumRec(arr,n-1,memo)# Store the max of two choices in the memo array and return itmemo[n]=max(pick,notPick)returnmemo[n]defmaxSum(arr):n=len(arr)# Initialize memo array with -1memo=[-1]*(n+1)returnmaxSumRec(arr,n,memo)if__name__=="__main__":arr=[6,7,1,3,8,2,4]print(maxSum(arr))
C#
// C# Program to find maximum sum with no two adjacentusingSystem;classGfG{staticintmaxSumRec(int[]arr,intn,int[]memo){if(n<=0)return0;if(n==1)returnarr[0];// Check if the result is already computedif(memo[n]!=-1)returnmemo[n];intpick=arr[n-1]+maxSumRec(arr,n-2,memo);intnotPick=maxSumRec(arr,n-1,memo);// Store the max of two choices in the memo array and return itmemo[n]=Math.Max(pick,notPick);returnmemo[n];}// Function to calculate the maximum Sum valuestaticintmaxSum(int[]arr){intn=arr.Length;// Initialize memo array with -1int[]memo=newint[n+1];for(inti=0;i<=n;i++){memo[i]=-1;}returnmaxSumRec(arr,n,memo);}staticvoidMain(){int[]arr={6,7,1,3,8,2,4};Console.WriteLine(maxSum(arr));}}
JavaScript
// JS Program to find maximum sum with no two adjacentfunctionmaxSumRec(arr,n,memo){if(n<=0)return0;if(n===1)returnarr[0];// Check if the result is already computedif(memo[n]!==-1)returnmemo[n];constpick=arr[n-1]+maxSumRec(arr,n-2,memo);constnotPick=maxSumRec(arr,n-1,memo);// Store the max of two choices in the memo array and return itmemo[n]=Math.max(pick,notPick);returnmemo[n];}// Function to calculate the maximum Sum valuefunctionmaxSum(arr){constn=arr.length;// Initialize memo array with -1constmemo=newArray(n+1).fill(-1);returnmaxSumRec(arr,n,memo);}constarr=[6,7,1,3,8,2,4];console.log(maxSum(arr));
Output
19
Time Complexity: O(n). Every element is computed only once. Auxiliary Space: O(n).For recursion stack space and memo array.
[Expected Approach 1] Using Tabulation - O(n) Time and O(n) Space
The idea is to build the solution in bottom-up manner. We create a dp[] array of size n+1 where dp[i] represents the maximum sum that can be obtained with first i elements. We first fill the known values, dp[0] and dp[1] and then fill the remaining values using the formula: dp[i] = max(arr[i] + dp[i - 2], dp[i - 1]). The final result will be stored at dp[n].
C++
#include<iostream>#include<vector>usingnamespacestd;// Function to calculate the maximum Sum value using bottom-up DPintmaxSum(vector<int>&arr){intn=arr.size();// Create a dp array to store the maximum sum at each elementvector<int>dp(n+1,0);// Base casesdp[0]=0;dp[1]=arr[0];// Fill the dp array using the bottom-up approachfor(inti=2;i<=n;i++)dp[i]=max(arr[i-1]+dp[i-2],dp[i-1]);returndp[n];}intmain(){vector<int>arr={6,7,1,3,8,2,4};cout<<maxSum(arr)<<endl;return0;}
C
#include<stdio.h>intmax(inta,intb){return(a>b)?a:b;}intmaxSum(int*arr,intn){// Create a dp array to store the// maximum sum at each elementintdp[n+1];dp[0]=0;dp[1]=arr[0];// Fill the dp array using the// bottom-up approachfor(inti=2;i<=n;i++)dp[i]=max(arr[i-1]+dp[i-2],dp[i-1]);returndp[n];}intmain(){intarr[]={6,7,1,3,8,2,4};intn=sizeof(arr)/sizeof(arr[0]);printf("%d\n",maxSum(arr,n));return0;}
Java
classGfG{// Function to calculate the maximum Sum value using bottom-up DPstaticintmaxSum(int[]arr){intn=arr.length;// Create a dp array to store the maximum sum at each elementint[]dp=newint[n+1];// Base casesdp[0]=0;dp[1]=arr[0];// Fill the dp array using the bottom-up approachfor(inti=2;i<=n;i++){dp[i]=Math.max(arr[i-1]+dp[i-2],dp[i-1]);}returndp[n];}publicstaticvoidmain(String[]args){int[]arr={6,7,1,3,8,2,4};System.out.println(maxSum(arr));}}
Python
defmaxSum(arr):n=len(arr)# Create a dp array to store the maximum sum at each elementdp=[0]*(n+1)# Base casesdp[0]=0dp[1]=arr[0]# Fill the dp array using the bottom-up approachforiinrange(2,n+1):dp[i]=max(arr[i-1]+dp[i-2],dp[i-1])returndp[n]arr=[6,7,1,3,8,2,4]print(maxSum(arr))
C#
usingSystem;classGfG{// Function to calculate the maximum Sum value using bottom-up DPstaticintmaxSum(int[]arr){intn=arr.Length;// Create a dp array to store the maximum sum at each elementint[]dp=newint[n+1];// Base casesdp[0]=0;dp[1]=arr[0];// Fill the dp array using the bottom-up approachfor(inti=2;i<=n;i++){dp[i]=Math.Max(arr[i-1]+dp[i-2],dp[i-1]);}returndp[n];}staticvoidMain(){int[]arr={6,7,1,3,8,2,4};Console.WriteLine(maxSum(arr));}}
JavaScript
functionmaxSum(arr){constn=arr.length;// Create a dp array to store the maximum sum at each elementconstdp=newArray(n+1).fill(0);// Base casesdp[0]=0;dp[1]=arr[0];// Fill the dp array using the bottom-up approachfor(leti=2;i<=n;i++)dp[i]=Math.max(arr[i-1]+dp[i-2],dp[i-1]);returndp[n];}constarr=[6,7,1,3,8,2,4];console.log(maxSum(arr));
Output
19
Time Complexity: O(n), Every element is computed only once. Auxiliary Space O(n), We are using a dp array of size n.
[Expected Approach 2] Space-Optimized DP - O(n) Time and O(1) Space
On observing the dp[] array in the previous approach, it can be seen that the answer at the current index depends only on the last two values. In other words, dp[i] depends only on dp[i - 1] and dp[i - 2]. So, instead of storing the result in an array, we can simply use two variables to store the last and second last result.
C++
#include<iostream>#include<vector>usingnamespacestd;// Function to calculate the maximum Sum valueintmaxSum(vector<int>&arr){intn=arr.size();if(n==0)return0;if(n==1)returnarr[0];// Set previous 2 valuesintsecondLast=0,last=arr[0];// Compute current value using previous two values// The final current value would be our resultintres;for(inti=1;i<n;i++){res=max(arr[i]+secondLast,last);secondLast=last;last=res;}returnres;}intmain(){vector<int>arr={6,7,1,3,8,2,4};cout<<maxSum(arr)<<endl;return0;}
C
#include<stdio.h>intmax(inta,intb){return(a>b)?a:b;}// Function to calculate the maximum Sum valueintmaxSum(intarr[],intn){if(n==0)return0;if(n==1)returnarr[0];// Set previous 2 valuesintsecondLast=0,last=arr[0];// Compute current value using previous// two values. The final current value// would be our resultintres;for(inti=1;i<n;i++){res=max(arr[i]+secondLast,last);secondLast=last;last=res;}returnres;}intmain(){intarr[]={6,7,1,3,8,2,4};intn=sizeof(arr)/sizeof(arr[0]);printf("%d\n",maxSum(arr,n));return0;}
Java
importjava.util.Arrays;classGfG{// Function to calculate the maximum Sum valuestaticintmaxSum(int[]arr){intn=arr.length;if(n==0)return0;if(n==1)returnarr[0];// Set previous 2 valuesintsecondLast=0,last=arr[0];// Compute current value using previous// two values. The final current value// would be our resultintres=0;for(inti=1;i<n;i++){res=Math.max(arr[i]+secondLast,last);secondLast=last;last=res;}returnres;}publicstaticvoidmain(String[]args){int[]arr={6,7,1,3,8,2,4};System.out.println(maxSum(arr));}}
Python
# Function to calculate the maximum Sum valuedefmaxSum(arr):n=len(arr)ifn==0:return0ifn==1:returnarr[0]# Set previous 2 valuessecondLast=0last=arr[0]# Compute current value using previous two values# The final current value would be our resultres=0foriinrange(1,n):res=max(arr[i]+secondLast,last)secondLast=lastlast=resreturnresarr=[6,7,1,3,8,2,4]print(maxSum(arr))
C#
usingSystem;classGfG{// Function to calculate the maximum Sum valuestaticintmaxSum(int[]arr){intn=arr.Length;if(n==0)return0;if(n==1)returnarr[0];// Set previous 2 valuesintsecondLast=0,last=arr[0];// Compute current value using previous two values// The final current value would be our resultintres=0;for(inti=1;i<n;i++){res=Math.Max(arr[i]+secondLast,last);secondLast=last;last=res;}returnres;}staticvoidMain(){int[]arr={6,7,1,3,8,2,4};Console.WriteLine(maxSum(arr));}}
JavaScript
// Function to calculate the maximum Sum valuefunctionmaxSum(arr){constn=arr.length;if(n===0)return0;if(n===1)returnarr[0];// Set previous 2 valuesletsecondLast=0,last=arr[0];// Compute current value using previous two values// The final current value would be our resultletres;for(leti=1;i<n;i++){res=Math.max(arr[i]+secondLast,last);secondLast=last;last=res;}returnres;}constarr=[6,7,1,3,8,2,4];console.log(maxSum(arr));
Output
19
Time Complexity: O(n), Every value is computed only once. Auxiliary Space: O(1), as we are using only two variables.