Maximum sum in circular array such that no two elements are adjacent
Given a circular array containing of positive integers value. The task is to find the maximum sum of a subsequence with the constraint that no 2 numbers in the sequence should be adjacent in the array.
Examples:
Input: circular arr = {1, 2, 3, 1}
Output : 4
subsequence will be(1, 3), hence 1 + 3 = 4
Input: circular arr = {1, 2, 3, 4, 5, 1}
Output: 9
subsequence will be(1, 3, 5), hence 1 + 3 + 5 = 9
Naive Approach:
This problem is extension to the problem https://www.geeksforgeeks.org/find-maximum-possible-stolen-value-houses/ .In this problem the arr elements are arranged in circular fashion so the 1st and the last element are also adjacent. So we can not take first and last element together so we can take either of the element1 or last element.
So first we can take element 1 and exclude last element and calculate the maximum sum subsequence where no two selected elements are adjacent and then also we can calculate another answer by excluding 1st element and including last element. And we will take maximum of two.
Implementation of recursion approach:
C++
#include<iostream>
using namespace std;
int helper( int * arr, int n)
{
if (n < 0) {
return 0;
}
if (n == 0) {
return arr[0];
}
int pick = arr[n] + helper(arr, n - 2);
int notPick = helper(arr, n - 1);
return max(pick, notPick);
}
int maxLoot( int * arr, int n)
{
int ans1 = helper(arr, n - 1);
int ans2 = helper(arr + 1, n - 1);
return max(ans1, ans2);
}
int main()
{
int arr[] = { 1, 2, 3, 1 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << "Maximum loot possible : "
<< maxLoot(arr, n - 1);
return 0;
}
|
Java
import java.io.*;
class GFG {
static int helper( int arr[], int l, int n)
{
if (n < 0 ) {
return 0 ;
}
if (n == 0 ) {
return arr[ 0 ];
}
int pick = arr[n] + helper(arr,l, n - 2 );
int notPick = helper(arr,l, n - 1 );
return Math.max(pick, notPick);
}
static int findMaxSum( int arr[], int n)
{
int ans1 = helper(arr, 0 , n - 1 );
int ans2 = helper(arr, 1 , n - 1 );
return Math.max(ans1, ans2);
}
public static void main (String[] args) {
int arr[] = { 1 , 2 , 3 , 1 };
int n = arr.length;
System.out.println( "Maximum loot possible : " + findMaxSum(arr, n));
}
}
|
Python3
def helper(arr, n):
if n < 0 :
return 0
if n = = 0 :
return arr[ 0 ]
pick = arr[n] + helper(arr, n - 2 )
notPick = helper(arr, n - 1 )
return max (pick, notPick)
def maxLoot(arr, n):
ans1 = helper(arr, n - 1 )
ans2 = helper(arr[ 1 :], n - 1 )
return max (ans1, ans2)
if __name__ = = "__main__" :
arr = [ 1 , 2 , 3 , 1 ]
n = len (arr)
print ( "Maximum loot possible : " , maxLoot(arr, n - 1 ))
|
C#
using System;
public class GFG
{
public static int helper( int [] arr, int l, int n)
{
if (n < 0)
{
return 0;
}
if (n == 0)
{
return arr[0];
}
var pick = arr[n] + GFG.helper(arr, l, n - 2);
var notPick = GFG.helper(arr, l, n - 1);
return Math.Max(pick,notPick);
}
public static int findMaxSum( int [] arr, int n)
{
var ans1 = GFG.helper(arr, 0, n - 1);
var ans2 = GFG.helper(arr, 1, n - 1);
return Math.Max(ans1,ans2);
}
public static void Main(String[] args)
{
int [] arr = {1, 2, 3, 1};
var n = arr.Length;
Console.WriteLine( "Maximum loot possible : " + GFG.findMaxSum(arr, n).ToString());
}
}
|
Javascript
function helper(arr, l, n)
{
if (n < 0)
{
return 0;
}
if (n == 0)
{
return arr[0];
}
var pick = arr[n] + helper(arr, l, n - 2);
var notPick = helper(arr, l, n - 1);
return Math.max(pick,notPick);
}
function findMaxSum(arr, n)
{
var ans1 = helper(arr, 0, n - 1);
var ans2 = helper(arr, 1, n - 1);
return Math.max(ans1,ans2);
}
var arr = [1, 2, 3, 1];
var n = arr.length;
console.log( "Maximum loot possible : " + findMaxSum(arr, n));
|
Output
Maximum loot possible : 4
Complexity Analysis:
- Time Complexity: O(2n).
- Auxiliary Space: O(N)
Approach The problem can be solved using DP. An approach has already been discussed in this post, but it for an array. We can treat the circular subarray a two arrays one from (0th to n-2-th) and (1st to n-1-th) index, and use the approach used in the previous post. The maximum sum returned by both will be the answer.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
int maxSum1( int arr[], int n)
{
int dp[n];
int maxi = 0;
for ( int i = 0; i < n - 1; i++) {
dp[i] = arr[i];
if (maxi < arr[i])
maxi = arr[i];
}
for ( int i = 2; i < n - 1; i++) {
for ( int j = 0; j < i - 1; j++) {
if (dp[i] < dp[j] + arr[i]) {
dp[i] = dp[j] + arr[i];
if (maxi < dp[i])
maxi = dp[i];
}
}
}
return maxi;
}
int maxSum2( int arr[], int n)
{
int dp[n];
int maxi = 0;
for ( int i = 1; i < n; i++) {
dp[i] = arr[i];
if (maxi < arr[i])
maxi = arr[i];
}
for ( int i = 3; i < n; i++) {
for ( int j = 1; j < i - 1; j++) {
if (dp[i] < arr[i] + dp[j]) {
dp[i] = arr[i] + dp[j];
if (maxi < dp[i])
maxi = dp[i];
}
}
}
return maxi;
}
int findMaxSum( int arr[], int n)
{
return max(maxSum1(arr, n), maxSum2(arr, n));
}
int main()
{
int arr[] = { 1, 2, 3, 1 };
int n = sizeof (arr)/ sizeof (arr[0]);
cout << findMaxSum(arr, n);
return 0;
}
|
Java
import java.io.*;
class GFG {
static int maxSum1( int arr[], int n)
{
int dp[]= new int [n];
int maxi = 0 ;
for ( int i = 0 ; i < n - 1 ; i++) {
dp[i] = arr[i];
if (maxi < arr[i])
maxi = arr[i];
}
for ( int i = 2 ; i < n - 1 ; i++) {
for ( int j = 0 ; j < i - 1 ; j++) {
if (dp[i] < dp[j] + arr[i]) {
dp[i] = dp[j] + arr[i];
if (maxi < dp[i])
maxi = dp[i];
}
}
}
return maxi;
}
static int maxSum2( int arr[], int n)
{
int dp[]= new int [n];
int maxi = 0 ;
for ( int i = 1 ; i < n; i++) {
dp[i] = arr[i];
if (maxi < arr[i])
maxi = arr[i];
}
for ( int i = 3 ; i < n; i++) {
for ( int j = 1 ; j < i - 1 ; j++) {
if (dp[i] < arr[i] + dp[j]) {
dp[i] = arr[i] + dp[j];
if (maxi < dp[i])
maxi = dp[i];
}
}
}
return maxi;
}
static int findMaxSum( int arr[], int n)
{
int t=Math.max(maxSum1(arr, n), maxSum2(arr, n));
return t;
}
public static void main (String[] args) {
int arr[] = { 1 , 2 , 3 , 1 };
int n = arr.length;
System.out.println(findMaxSum(arr, n));
}
}
|
Python 3
def maxSum1(arr, n):
dp = [ 0 ] * n
maxi = 0
for i in range (n - 1 ):
dp[i] = arr[i]
if (maxi < arr[i]):
maxi = arr[i]
for i in range ( 2 , n - 1 ):
for j in range (i - 1 ) :
if (dp[i] < dp[j] + arr[i]):
dp[i] = dp[j] + arr[i]
if (maxi < dp[i]):
maxi = dp[i]
return maxi
def maxSum2(arr, n):
dp = [ 0 ] * n
maxi = 0
for i in range ( 1 , n):
dp[i] = arr[i]
if (maxi < arr[i]):
maxi = arr[i]
for i in range ( 3 , n):
for j in range ( 1 , i - 1 ) :
if (dp[i] < arr[i] + dp[j]):
dp[i] = arr[i] + dp[j]
if (maxi < dp[i]):
maxi = dp[i]
return maxi
def findMaxSum(arr, n):
return max (maxSum1(arr, n), maxSum2(arr, n))
if __name__ = = "__main__" :
arr = [ 1 , 2 , 3 , 1 ]
n = len (arr)
print (findMaxSum(arr, n))
|
C#
using System;
class GFG
{
static int maxSum1( int []arr, int n)
{
int []dp = new int [n];
int maxi = 0;
for ( int i = 0; i < n - 1; i++)
{
dp[i] = arr[i];
if (maxi < arr[i])
maxi = arr[i];
}
for ( int i = 2; i < n - 1; i++)
{
for ( int j = 0; j < i - 1; j++)
{
if (dp[i] < dp[j] + arr[i])
{
dp[i] = dp[j] + arr[i];
if (maxi < dp[i])
maxi = dp[i];
}
}
}
return maxi;
}
static int maxSum2( int []arr, int n)
{
int []dp = new int [n];
int maxi = 0;
for ( int i = 1; i < n; i++)
{
dp[i] = arr[i];
if (maxi < arr[i])
maxi = arr[i];
}
for ( int i = 3; i < n; i++)
{
for ( int j = 1; j < i - 1; j++)
{
if (dp[i] < arr[i] + dp[j])
{
dp[i] = arr[i] + dp[j];
if (maxi < dp[i])
maxi = dp[i];
}
}
}
return maxi;
}
static int findMaxSum( int []arr, int n)
{
int t = Math.Max(maxSum1(arr, n),
maxSum2(arr, n));
return t;
}
static public void Main ()
{
int []arr = { 1, 2, 3, 1 };
int n = arr.Length;
Console.WriteLine(findMaxSum(arr, n));
}
}
|
PHP
<?php
function maxSum1( $arr , $n )
{
$dp [ $n ] = array ();
$maxi = 0;
for ( $i = 0; $i < $n - 1; $i ++)
{
$dp [ $i ] = $arr [ $i ];
if ( $maxi < $arr [ $i ])
$maxi = $arr [ $i ];
}
for ( $i = 2; $i < $n - 1; $i ++)
{
for ( $j = 0; $j < $i - 1; $j ++)
{
if ( $dp [ $i ] < $dp [ $j ] + $arr [ $i ])
{
$dp [ $i ] = $dp [ $j ] + $arr [ $i ];
if ( $maxi < $dp [ $i ])
$maxi = $dp [ $i ];
}
}
}
return $maxi ;
}
function maxSum2( $arr , $n )
{
$dp [ $n ] = array ();
$maxi = 0;
for ( $i = 1; $i < $n ; $i ++)
{
$dp [ $i ] = $arr [ $i ];
if ( $maxi < $arr [ $i ])
$maxi = $arr [ $i ];
}
for ( $i = 3; $i < $n ; $i ++)
{
for ( $j = 1; $j < $i - 1; $j ++)
{
if ( $dp [ $i ] < $arr [ $i ] + $dp [ $j ])
{
$dp [ $i ] = $arr [ $i ] + $dp [ $j ];
if ( $maxi < $dp [ $i ])
$maxi = $dp [ $i ];
}
}
}
return $maxi ;
}
function findMaxSum( $arr , $n )
{
return max(maxSum1( $arr , $n ),
maxSum2( $arr , $n ));
}
$arr = array (1, 2, 3, 1 );
$n = sizeof( $arr );
echo findMaxSum( $arr , $n );
?>
|
Javascript
<script>
function maxSum1(arr, n)
{
let dp = new Array(n);
let maxi = 0;
for (i = 0; i < n - 1; i++)
{
dp[i] = arr[i];
if (maxi < arr[i])
maxi = arr[i];
}
for (i = 2; i < n - 1; i++)
{
for (j = 0; j < i - 1; j++)
{
if (dp[i] < dp[j] + arr[i])
{
dp[i] = dp[j] + arr[i];
if (maxi < dp[i])
maxi = dp[i];
}
}
}
return maxi;
}
function maxSum2(arr, n)
{
let dp = new Array(n);
let maxi = 0;
for (i = 1; i < n; i++)
{
dp[i] = arr[i];
if (maxi < arr[i])
maxi = arr[i];
}
for (i = 3; i < n; i++)
{
for (j = 1; j < i - 1; j++)
{
if (dp[i] < arr[i] + dp[j])
{
dp[i] = arr[i] + dp[j];
if (maxi < dp[i])
maxi = dp[i];
}
}
}
return maxi;
}
function findMaxSum(arr, n)
{
let t = Math.max(maxSum1(arr, n),
maxSum2(arr, n));
return t;
}
let arr = [1, 2, 3, 1 ];
let n = arr.length;
document.write(findMaxSum(arr, n));
</script>
|
Time Complexity: O(N^2)
Auxiliary Space: O(N)
Space optimization approach: As we can see the dp[i] is calculated from previous values so we can just store those previous values in variables.
Implementation:
C++14
#include <iostream>
using namespace std;
int findMaxSum( int arr[], int n)
{
if (n == 0)
return 0;
int value1 = arr[0];
if (n == 1)
return value1;
int value2 = 0;
int max_val1, max_val2;
for ( int i = 1; i < n - 1; i++) {
int first = value1;
int second = arr[i];
if (i > 1) {
second += value2;
}
int curr = max(first, second);
value2 = value1;
value1 = curr;
}
max_val1 = value1;
value1 = arr[1];
value2 = 0;
for ( int i = 2; i < n; i++) {
int first = value1;
int second = arr[i];
if (i > 1) {
second += value2;
}
int curr = max(first, second);
value2 = value1;
value1 = curr;
}
max_val2 = value1;
return max(max_val1, max_val2);
}
int main()
{
int arr[] = { 6, 7, 1, 3, 8, 2, 4 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << findMaxSum(arr, n);
return 0;
}
|
Java
public class GFG {
static int findMaxSum( int [] arr, int n)
{
if (n == 0 )
return 0 ;
int value1 = arr[ 0 ];
if (n == 1 )
return value1;
int value2 = 0 ;
int max_val1, max_val2;
for ( int i = 1 ; i < n - 1 ; i++) {
int first = value1;
int second = arr[i];
if (i > 1 ) {
second += value2;
}
int curr = Math.max(first, second);
value2 = value1;
value1 = curr;
}
max_val1 = value1;
value1 = arr[ 1 ];
value2 = 0 ;
for ( int i = 2 ; i < n; i++) {
int first = value1;
int second = arr[i];
if (i > 1 ) {
second += value2;
}
int curr = Math.max(first, second);
value2 = value1;
value1 = curr;
}
max_val2 = value1;
return Math.max(max_val1, max_val2);
}
public static void main (String[] args)
{
int arr[] = { 6 , 7 , 1 , 3 , 8 , 2 , 4 };
int n = arr.length;
System.out.println(findMaxSum(arr, n));
}
}
|
Python3
def findMaxSum(arr, n):
if n = = 0 :
return 0
value1 = arr[ 0 ]
if n = = 1 :
return value1
value2 = 0
max_val1, max_val2 = 0 , 0
for i in range ( 1 ,n) :
first = value1
second = arr[i]
if i > 1 :
second + = value2
curr = max (first, second)
value2 = value1
value1 = curr
max_val1 = value1
value1 = arr[ 1 ]
value2 = 0
for i in range ( 2 ,n) :
first = value1
second = arr[i]
if i > 1 :
second + = value2
curr = max (first, second)
value2 = value1
value1 = curr
max_val2 = value1
return max (max_val1, max_val2)
if __name__ = = "__main__" :
arr = [ 6 , 7 , 1 , 3 , 8 , 2 , 4 ]
n = len (arr)
print (findMaxSum(arr, n))
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
public class GFG {
static int findMaxSum( int [] arr, int n)
{
if (n == 0)
return 0;
int value1 = arr[0];
if (n == 1)
return value1;
int value2 = 0;
int max_val1, max_val2;
for ( int i = 1; i < n - 1; i++) {
int first = value1;
int second = arr[i];
if (i > 1) {
second += value2;
}
int curr = Math.Max(first, second);
value2 = value1;
value1 = curr;
}
max_val1 = value1;
value1 = arr[1];
value2 = 0;
for ( int i = 2; i < n; i++) {
int first = value1;
int second = arr[i];
if (i > 1) {
second += value2;
}
int curr = Math.Max(first, second);
value2 = value1;
value1 = curr;
}
max_val2 = value1;
return Math.Max(max_val1, max_val2);
}
public static void Main( string [] args)
{
int [] arr = { 6, 7, 1, 3, 8, 2, 4 };
int n = arr.Length;
Console.WriteLine(findMaxSum(arr, n));
}
}
|
Javascript
function findMaxSum(arr, n) {
if (n == 0)
return 0;
let value1 = arr[0];
if (n == 1)
return value1;
let value2 = 0;
let max_val1, max_val2;
for (let i = 1; i < n - 1; i++) {
let first = value1;
let second = arr[i];
if (i > 1) {
second += value2;
}
let curr = Math.max(first, second);
value2 = value1;
value1 = curr;
}
max_val1 = value1;
value1 = arr[1];
value2 = 0;
for (let i = 2; i < n; i++) {
let first = value1;
let second = arr[i];
if (i > 1) {
second += value2;
}
let curr = Math.max(first, second);
value2 = value1;
value1 = curr;
}
max_val2 = value1;
return Math.max(max_val1, max_val2);
}
let arr = [6, 7, 1, 3, 8, 2, 4];
let n = arr.length;
console.log(findMaxSum(arr, n));
return 0;
|
Complexity Analysis:
- Time Complexity: O(N).
- Space Complexity: O(1).
Last Updated :
04 Mar, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...