Given an array of positive numbers, find the maximum sum of a subsequence with the constraint that no 2 numbers in the sequence should be adjacent in the array. So 3 2 7 10 should return 13 (sum of 3 and 10) or 3 2 5 10 7 should return 15 (sum of 3, 5, and 7).
Examples:Â
Input : arr[] = {3, 5, 3}
Output : 6
Explanation :
Selecting indexes 0 and 2 will maximise the sum
i.e 3+3 = 6
Input : arr[] = {2, 5, 2}
Output : 5
We have already discussed the efficient approach of solving this problem in the previous article.
However, we can also solve this problem using the Dynamic Programming approach.
Dynamic Programming Approach: Let’s decide the states of ‘dp’. Let dp[i] be the largest possible sum for the sub-array starting from index ‘i’ and ending at index ‘N-1’. Now, we have to find a recurrence relation between this state and a lower-order state.
In this case for an index ‘i’, we will have two choices. Â
1) Choose the current index:
In this case, the relation will be dp[i] = arr[i] + dp[i+2]
2) Skip the current index:
Relation will be dp[i] = dp[i+1]
We will choose the path that maximizes our result.Â
Thus, the final relation will be:Â Â
dp[i] = max(dp[i+2]+arr[i], dp[i+1])
Below is the implementation of the above approach:Â Â
C++
// C++ program to implement above approach Â
#include <bits/stdc++.h> #define maxLen 10 using namespace std; Â
// variable to store states of dp int dp[maxLen]; Â
// variable to check if a given state // has been solved bool v[maxLen]; Â
// Function to find the maximum sum subsequence // such that no two elements are adjacent int maxSum( int arr[], int i, int n) {     // Base case     if (i >= n)         return 0; Â
    // To check if a state has     // been solved     if (v[i])         return dp[i];     v[i] = 1; Â
    // Required recurrence relation     dp[i] = max(maxSum(arr, i + 1, n),                 arr[i] + maxSum(arr, i + 2, n)); Â
    // Returning the value     return dp[i]; } Â
// Driver code int main() { Â Â Â Â int arr[] = { 12, 9, 7, 33 }; Â
    int n = sizeof (arr) / sizeof ( int ); Â
    cout << maxSum(arr, 0, n); Â
    return 0; } |
Java
// Java program to implement above approach class GFG { Â
static int maxLen = 10 ; Â
// variable to store states of dp static int dp[] = new int [maxLen]; Â
// variable to check if a given state // has been solved static boolean v[] = new boolean [maxLen]; Â
// Function to find the maximum sum subsequence // such that no two elements are adjacent static int maxSum( int arr[], int i, int n) {     // Base case     if (i >= n)         return 0 ; Â
    // To check if a state has     // been solved     if (v[i])         return dp[i];     v[i] = true ; Â
    // Required recurrence relation     dp[i] = Math.max(maxSum(arr, i + 1 , n),                 arr[i] + maxSum(arr, i + 2 , n)); Â
    // Returning the value     return dp[i]; } Â
// Driver code public static void main(String args[]) { Â Â Â Â int arr[] = { 12 , 9 , 7 , 33 }; Â Â Â Â int n = arr.length; Â Â Â Â System.out.println( maxSum(arr, 0 , n)); } } Â
// This code is contributed by Arnab Kundu |
Python3
# Python 3 program to implement above approach maxLen = 10 Â
# variable to store states of dp dp = [ 0 for i in range (maxLen)] Â
# variable to check if a given state # has been solved v = [ 0 for i in range (maxLen)] Â
# Function to find the maximum sum subsequence # such that no two elements are adjacent def maxSum(arr, i, n):     # Base case     if (i > = n):         return 0 Â
    # To check if a state has     # been solved     if (v[i]):         return dp[i]     v[i] = 1 Â
    # Required recurrence relation     dp[i] = max (maxSum(arr, i + 1 , n),             arr[i] + maxSum(arr, i + 2 , n)) Â
    # Returning the value     return dp[i] Â
# Driver code if __name__ = = '__main__' : Â Â Â Â arr = [ 12 , 9 , 7 , 33 ] Â
    n = len (arr)     print (maxSum(arr, 0 , n)) Â
# This code is contributed by # Surendra_Gangwar |
C#
// C# program to implement above approach using System; Â
class GFG { Â
static int maxLen = 10; Â
// variable to store states of dp static int [] dp = new int [maxLen]; Â
// variable to check if a given state // has been solved static bool [] v = new bool [maxLen]; Â
// Function to find the maximum sum subsequence // such that no two elements are adjacent static int maxSum( int [] arr, int i, int n) {     // Base case     if (i >= n)         return 0; Â
    // To check if a state has     // been solved     if (v[i])         return dp[i];     v[i] = true ; Â
    // Required recurrence relation     dp[i] = Math.Max(maxSum(arr, i + 1, n),                 arr[i] + maxSum(arr, i + 2, n)); Â
    // Returning the value     return dp[i]; } Â
// Driver code public static void Main() { Â Â Â Â int [] arr = { 12, 9, 7, 33 }; Â Â Â Â int n = arr.Length; Â Â Â Â Console.Write( maxSum(arr, 0, n)); } } Â
// This code is contributed by ChitraNayal |
Javascript
<script> Â
// Javascript program to implement above approach var maxLen = 10; Â
// variable to store states of dp var dp = Array(maxLen); Â
// variable to check if a given state // has been solved var v = Array(maxLen); Â
// Function to find the maximum sum subsequence // such that no two elements are adjacent function maxSum(arr, i, n) {     // Base case     if (i >= n)         return 0; Â
    // To check if a state has     // been solved     if (v[i])         return dp[i];     v[i] = 1; Â
    // Required recurrence relation     dp[i] = Math.max(maxSum(arr, i + 1, n),                 arr[i] + maxSum(arr, i + 2, n)); Â
    // Returning the value     return dp[i]; } Â
// Driver code var arr = [12, 9, 7, 33 ]; var n = arr.length; document.write( maxSum(arr, 0, n)); Â
</script> |
PHP
<?php // PHP program to implement above approach Â
$maxLen = 10; Â
// variable to store states of dp $dp = array_fill (0, $GLOBALS [ 'maxLen' ], 0); Â
// variable to check if a given state // has been solved $v = array_fill (0, $GLOBALS [ 'maxLen' ], 0); Â
// Function to find the maximum sum subsequence // such that no two elements are adjacent function maxSum( $arr , $i , $n ) {     // Base case     if ( $i >= $n )         return 0; Â
    // To check if a state has     // been solved     if ( $GLOBALS [ 'v' ][ $i ])         return $GLOBALS [ 'dp' ][ $i ];              $GLOBALS [ 'v' ][ $i ] = 1; Â
    // Required recurrence relation     $GLOBALS [ 'dp' ][ $i ] = max(maxSum( $arr , $i + 1, $n ),                 $arr [ $i ] + maxSum( $arr , $i + 2, $n )); Â
    // Returning the value     return $GLOBALS [ 'dp' ][ $i ]; } Â
    // Driver code     $arr = array ( 12, 9, 7, 33 ); Â
    $n = count ( $arr ); Â
    echo maxSum( $arr , 0, $n ); Â
    // This code is contributed by AnkitRai01 ?> |
45
Time Complexity : O(n)
Auxiliary Space : O(10)
Efficient approach : Using DP Tabulation method ( Iterative approach )
The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memoization(top-down) because memoization method needs extra stack space of recursion calls.
Steps to solve this problem :
- Create a DP of size N+1 to store the solution of the subproblems.
- Initialize the DP Â with base cases
- Now Iterate over subproblems to get the value of current problem form previous computation of subproblems stored in DP
- Return the final solution stored in dp[n-1].
Implementation :
C++
#include <bits/stdc++.h> using namespace std; Â
// Function to find the maximum sum subsequence // such that no two elements are adjacent int maxSum( int arr[], int n) {     // Base case     if (n == 0)         return 0;     if (n == 1)         return arr[0];     if (n == 2)         return max(arr[0], arr[1]); Â
    // DP table to store solutions to subproblems     int dp[n]; Â
    // Initializing base cases     dp[0] = arr[0];     dp[1] = max(arr[0], arr[1]); Â
    // Filling up the DP table using recurrence relation     for ( int i = 2; i < n; i++) {         dp[i] = max(dp[i - 1], arr[i] + dp[i - 2]);     } Â
    // Returning the final answer     return dp[n - 1]; } Â
// Driver code int main() { Â Â Â Â int arr[] = { 12, 9, 7, 33 }; Â Â Â Â int n = sizeof (arr) / sizeof (arr[0]); Â Â Â Â cout << maxSum(arr, n) << endl; Â Â Â Â return 0; } |
Java
import java.util.*; Â
public class Main {     // Function to find the maximum sum subsequence     // such that no two elements are adjacent     public static int maxSum( int [] arr, int n)     {         // Base case         if (n == 0 )             return 0 ;         if (n == 1 )             return arr[ 0 ];         if (n == 2 )             return Math.max(arr[ 0 ], arr[ 1 ]); Â
        // DP table to store solutions to subproblems         int [] dp = new int [n]; Â
        // Initializing base cases         dp[ 0 ] = arr[ 0 ];         dp[ 1 ] = Math.max(arr[ 0 ], arr[ 1 ]); Â
        // Filling up the DP table using recurrence relation         for ( int i = 2 ; i < n; i++) {             dp[i] = Math.max(dp[i - 1 ], arr[i] + dp[i - 2 ]);         } Â
        // Returning the final answer         return dp[n - 1 ];     } Â
    // Driver code     public static void main(String[] args)     {         int [] arr = { 12 , 9 , 7 , 33 };         int n = arr.length;         System.out.println(maxSum(arr, n));     } } |
Python3
def maxSum(arr, n):     # Base case     if n = = 0 :         return 0     if n = = 1 :         return arr[ 0 ]     if n = = 2 :         return max (arr[ 0 ], arr[ 1 ]) Â
    # DP table to store solutions to subproblems     dp = [ 0 ] * n Â
    # Initializing base cases     dp[ 0 ] = arr[ 0 ]     dp[ 1 ] = max (arr[ 0 ], arr[ 1 ]) Â
    # Filling up the DP table using recurrence relation     for i in range ( 2 , n):         dp[i] = max (dp[i - 1 ], arr[i] + dp[i - 2 ]) Â
    # Returning the final answer     return dp[n - 1 ] Â
Â
arr = [ 12 , 9 , 7 , 33 ] n = len (arr) print (maxSum(arr, n)) |
C#
using System; Â
class GFG {     // Function to find the maximum sum subsequence     // such that no two elements are adjacent     static int maxSum( int [] arr, int n)     {         // Base case         if (n == 0)             return 0;         if (n == 1)             return arr[0];         if (n == 2)             return Math.Max(arr[0], arr[1]); Â
        // DP table to store solutions to subproblems         int [] dp = new int [n]; Â
        // Initializing base cases         dp[0] = arr[0];         dp[1] = Math.Max(arr[0], arr[1]); Â
        // Filling up the DP table using recurrence relation         for ( int i = 2; i < n; i++) {             dp[i] = Math.Max(dp[i - 1], arr[i] + dp[i - 2]);         } Â
        // Returning the final answer         return dp[n - 1];     } Â
    // Driver code     static void Main()     {         int [] arr = { 12, 9, 7, 33 };         int n = arr.Length;         Console.WriteLine(maxSum(arr, n));     } } |
Javascript
// Function to find the maximum sum subsequence // such that no two elements are adjacent function maxSum(arr) {     // Base cases     const n = arr.length;     if (n === 0)         return 0;     if (n === 1)         return arr[0];     if (n === 2)         return Math.max(arr[0], arr[1]); Â
    // DP array to store solutions to subproblems     const dp = new Array(n); Â
    // Initializing base cases     dp[0] = arr[0];     dp[1] = Math.max(arr[0], arr[1]); Â
    // Filling up the DP array using recurrence relation     for (let i = 2; i < n; i++) {         dp[i] = Math.max(dp[i - 1], arr[i] + dp[i - 2]);     } Â
    // Returning the final answer     return dp[n - 1]; } Â
// Driver code const arr = [12, 9, 7, 33]; console.log(maxSum(arr)); |
45
Time Complexity : O(n)
Auxiliary Space : O(n)
Another Approach(Using Greedy Strategy):
- Initialize include as the first element and exclude as 0.
- For each element in the array, update include as exclude + current element (considering the current element).
- Update exclude as the maximum of include and exclude (excluding the current element).
- Repeat steps 2 and 3 for all elements in the array.
- Finally, return the maximum of include and exclude as the maximum sum.
Below is the implementation of the above approach:Â Â
C++
#include <iostream> #include <algorithm> using namespace std; Â
int maxSumNoAdjacent( int arr[], int n) { Â Â Â Â if (n == 0) Â Â Â Â Â Â Â Â return 0; Â Â Â Â if (n == 1) Â Â Â Â Â Â Â Â return arr[0]; Â
    int include = arr[0];     int exclude = 0; Â
    for ( int i = 1; i < n; i++) {         int prevInclude = include;         include = exclude + arr[i];         exclude = max(prevInclude, exclude);     } Â
    return max(include, exclude); } Â
int main() { Â Â Â Â int arr[] = {12, 9, 7, 33}; Â Â Â Â int n = sizeof (arr) / sizeof (arr[0]); Â
    int maxSum = maxSumNoAdjacent(arr, n);     cout<< maxSum << endl; Â
    return 0; } |
Java
import java.util.Arrays; Â
public class Main { Â Â Â Â public static int maxSumNoAdjacent( int [] arr, int n) { Â Â Â Â Â Â Â Â if (n == 0 ) Â Â Â Â Â Â Â Â Â Â Â Â return 0 ; Â Â Â Â Â Â Â Â if (n == 1 ) Â Â Â Â Â Â Â Â Â Â Â Â return arr[ 0 ]; Â Â Â Â Â Â Â Â int include = arr[ 0 ]; Â Â Â Â Â Â Â Â int exclude = 0 ; Â Â Â Â Â Â Â Â for ( int i = 1 ; i < n; i++) { Â Â Â Â Â Â Â Â Â Â Â Â int prevInclude = include; Â Â Â Â Â Â Â Â Â Â Â Â include = exclude + arr[i]; Â Â Â Â Â Â Â Â Â Â Â Â exclude = Math.max(prevInclude, exclude); Â Â Â Â Â Â Â Â } Â Â Â Â Â Â Â Â return Math.max(include, exclude); Â Â Â Â } Â
    public static void main(String[] args) {         int [] arr = { 12 , 9 , 7 , 33 };         int n = arr.length;         int maxSum = maxSumNoAdjacent(arr, n);         System.out.println(maxSum);     } } |
Python
def maxSumNoAdjacent(arr, n):     if n = = 0 :         return 0     if n = = 1 :         return arr[ 0 ]     include = arr[ 0 ]     exclude = 0     for i in range ( 1 , n):         prevInclude = include         include = exclude + arr[i]         exclude = max (prevInclude, exclude)     return max (include, exclude) Â
arr = [ 12 , 9 , 7 , 33 ] n = len (arr) maxSum = maxSumNoAdjacent(arr, n) print (maxSum) |
C#
using System; Â
class Program { Â Â Â Â static int MaxSumNoAdjacent( int [] arr, int n) Â Â Â Â { Â Â Â Â Â Â Â Â if (n == 0) Â Â Â Â Â Â Â Â Â Â Â Â return 0; Â Â Â Â Â Â Â Â if (n == 1) Â Â Â Â Â Â Â Â Â Â Â Â return arr[0]; Â Â Â Â Â Â Â Â int include = arr[0]; Â Â Â Â Â Â Â Â int exclude = 0; Â Â Â Â Â Â Â Â for ( int i = 1; i < n; i++) Â Â Â Â Â Â Â Â { Â Â Â Â Â Â Â Â Â Â Â Â int prevInclude = include; Â Â Â Â Â Â Â Â Â Â Â Â include = exclude + arr[i]; Â Â Â Â Â Â Â Â Â Â Â Â exclude = Math.Max(prevInclude, exclude); Â Â Â Â Â Â Â Â } Â Â Â Â Â Â Â Â return Math.Max(include, exclude); Â Â Â Â } Â
    static void Main()     {         int [] arr = { 12, 9, 7, 33 };         int n = arr.Length;         int maxSum = MaxSumNoAdjacent(arr, n);         Console.WriteLine(maxSum);     } } |
Javascript
function maxSumNoAdjacent(arr, n) { Â Â Â Â if (n === 0) Â Â Â Â Â Â Â Â return 0; Â Â Â Â if (n === 1) Â Â Â Â Â Â Â Â return arr[0]; Â Â Â Â let include = arr[0]; Â Â Â Â let exclude = 0; Â Â Â Â for (let i = 1; i < n; i++) { Â Â Â Â Â Â Â Â let prevInclude = include; Â Â Â Â Â Â Â Â include = exclude + arr[i]; Â Â Â Â Â Â Â Â exclude = Math.max(prevInclude, exclude); Â Â Â Â } Â Â Â Â return Math.max(include, exclude); } Â
let arr = [12, 9, 7, 33]; let n = arr.length; let maxSum = maxSumNoAdjacent(arr, n); console.log(maxSum); |
PHP
<?php function maxSumNoAdjacent( $arr , $n ) { Â Â Â Â if ( $n == 0) Â Â Â Â Â Â Â Â return 0; Â Â Â Â if ( $n == 1) Â Â Â Â Â Â Â Â return $arr [0]; Â Â Â Â $include = $arr [0]; Â Â Â Â $exclude = 0; Â Â Â Â for ( $i = 1; $i < $n ; $i ++) { Â Â Â Â Â Â Â Â $prevInclude = $include ; Â Â Â Â Â Â Â Â $include = $exclude + $arr [ $i ]; Â Â Â Â Â Â Â Â $exclude = max( $prevInclude , $exclude ); Â Â Â Â } Â Â Â Â return max( $include , $exclude ); } $arr = [12, 9, 7, 33]; $n = count ( $arr ); $maxSum = maxSumNoAdjacent( $arr , $n ); echo $maxSum . "\n" ; ?> |
45
Time Complexity :O(n), where n is the size of the input array. This is because the code iterates through the array once in the for loop, performing a constant number of operations for each element.
Auxiliary Space :Â O(1), meaning it uses a constant amount of extra space. The space usage remains constant throughout the execution, regardless of the size of the input array. This is because the code only uses a few variables (include, exclude, prevInclude) to keep track of the maximum sum, and their space requirements do not depend on the size of the array.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!