Maximum sum in circular array such that no two elements are adjacent

Last Updated : 27 Jan, 2026

Given an array arr[] which represents houses arranged in a circle, where each house has a certain value. A thief aims to maximize the total stolen value without robbing two adjacent houses. Since the houses are in a circle, the first and last houses are also considered adjacent. Determine the maximum amount the thief can steal.

Examples: 

Input: arr[] = [2, 2, 3, 1, 2]
Output: 5
Explanation: Maximum stolen value: arr[0] + arr[2] = 2 + 3 = 5 or arr[2] + arr[4] = 3 + 2 = 5.

Input: arr[] = [2, 3, 2]
Output: 3
Explanation: arr[0] and arr[2] can't be robbed simultaneously because they are adjacent houses.

Try It Yourself
redirect icon

[Naive Approach] Using Recursion - O(2^n) Time and O(n) Space

The idea is to solve this problem by handling the circular constraint, where the first and last houses are adjacent.

To avoid robbing both of them together, we divide the problem into two linear cases:

  • Consider houses from index 0 to n−2 (exclude the last house).
  • Consider houses from index 1 to n−1 (exclude the first house).

For each case, the thief has two choices at every house:

  • Rob the current house → then skip the adjacent (previous) one and add the value of the current house.
  • Skip the current house → take the maximum value obtained so far.

We solve both cases separately using recursion and then take the maximum of the two results.


C++
//Driver Code Starts
#include <iostream>
#include <vector>
using namespace std;
//Driver Code Ends


// Calculate the maximum stolen value recursively
int maxValRec(vector<int> &arr, int i, int j) {
    
    // If no houses are left, return 0.
    if (i> j)  return 0;
  
      // If only 1 house is left, rob it. 
    if (i == j)  return arr[i];

    // Two Choices: 
    // Rob the jth house and skip the (j-1)th house 
    int pick = arr[j] + maxValRec(arr, i, j-2);
    
    // Skip the jth house
    int notPick = maxValRec(arr, i, j-1);

    // Return the max of two choices
    return max(pick, notPick);
}

// Function to calculate the maximum stolen value
int maxValue(vector<int>& arr) {
    int n = arr.size();
  
    int ans = 0;
    
    // Skip the last house
    ans = max(ans, maxValRec(arr, 0, n-2));
    
    // Skip the first house 
    ans = max(ans, maxValRec(arr, 1, n-1));
    
    return ans;
}


//Driver Code Starts
int main() {
    vector<int> arr = {2, 2, 3, 1, 2};
    cout << maxValue(arr);
    return 0;
}

//Driver Code Ends
Java
//Driver Code Starts
class GfG {
//Driver Code Ends


    // Calculate the maximum stolen value recursively
    static int maxValRec(int[] arr, int i, int j) {
        
        // If no houses are left, return 0.
        if (i > j) return 0;
    
        // If only 1 house is left, rob it. 
        if (i == j) return arr[i];

        // Two Choices: 
        // Rob the jth house and skip the (j-1)th house 
        int pick = arr[j] + maxValRec(arr, i, j - 2);
        
        // Skip the jth house
        int notPick = maxValRec(arr, i, j - 1);

        // Return the max of two choices
        return Math.max(pick, notPick);
    }

    // Function to calculate the maximum stolen value
    static int maxValue(int[] arr) {
        int n = arr.length;
    
        int ans = 0;
        
        // Skip the last house
        ans = Math.max(ans, maxValRec(arr, 0, n - 2));
        
        // Skip the first house 
        ans = Math.max(ans, maxValRec(arr, 1, n - 1));
        
        return ans;
    }


//Driver Code Starts
    public static void main(String[] args) {
        int[] arr = {2, 2, 3, 1, 2};
        System.out.println(maxValue(arr));
    }
}

//Driver Code Ends
Python
# Calculate the maximum stolen value recursively
def maxValRec(arr, i, j):
    
    # If no houses are left, return 0.
    if i > j:
        return 0

    # If only 1 house is left, rob it. 
    if i == j:
        return arr[i]

    # Two Choices: 
    # Rob the jth house and skip the (j-1)th house 
    pick = arr[j] + maxValRec(arr, i, j - 2)
    
    # Skip the jth house
    notPick = maxValRec(arr, i, j - 1)

    # Return the max of two choices
    return max(pick, notPick)

# Function to calculate the maximum stolen value
def maxValue(arr):
    n = len(arr)

    ans = 0
    
    # Skip the last house
    ans = max(ans, maxValRec(arr, 0, n - 2))
    
    # Skip the first house 
    ans = max(ans, maxValRec(arr, 1, n - 1))
    
    return ans


if __name__ == "__main__":
#Driver Code Starts
    arr = [2, 2, 3, 1, 2]
    print(maxValue(arr))

#Driver Code Ends
C#
//Driver Code Starts
using System;

class GfG {
//Driver Code Ends


    // Calculate the maximum stolen value recursively
    static int maxValRec(int[] arr, int i, int j) {
        
        // If no houses are left, return 0.
        if (i > j) return 0;
    
        // If only 1 house is left, rob it. 
        if (i == j) return arr[i];

        // Two Choices: 
        // Rob the jth house and skip the (j-1)th house 
        int pick = arr[j] + maxValRec(arr, i, j - 2);
        
        // Skip the jth house
        int notPick = maxValRec(arr, i, j - 1);

        // Return the max of two choices
        return Math.Max(pick, notPick);
    }

    // Function to calculate the maximum stolen value
    static int maxValue(int[] arr) {
        int n = arr.Length;

        int ans = 0;
        
        // Skip the last house
        ans = Math.Max(ans, maxValRec(arr, 0, n - 2));
        
        // Skip the first house 
        ans = Math.Max(ans, maxValRec(arr, 1, n - 1));
        
        return ans;
    }


//Driver Code Starts
    static void Main() {
        int[] arr = {2, 2, 3, 1, 2};
        Console.WriteLine(maxValue(arr));
    }
}

//Driver Code Ends
JavaScript
// Calculate the maximum stolen value recursively
function maxValRec(arr, i, j) {
    
    // If no houses are left, return 0.
    if (i > j) return 0;

    // If only 1 house is left, rob it. 
    if (i == j) return arr[i];

    // Two Choices: 
    // Rob the jth house and skip the (j-1)th house 
    let pick = arr[j] + maxValRec(arr, i, j - 2);
    
    // Skip the jth house
    let notPick = maxValRec(arr, i, j - 1);

    // Return the max of two choices
    return Math.max(pick, notPick);
}

// Function to calculate the maximum stolen value
function maxValue(arr) {
    let n = arr.length;

    let ans = 0;
    
    // Skip the last house
    ans = Math.max(ans, maxValRec(arr, 0, n - 2));
    
    // Skip the first house 
    ans = Math.max(ans, maxValRec(arr, 1, n - 1));
    
    return ans;
}

//Drievr Code
//Driver Code Starts
let arr = [2, 2, 3, 1, 2];
console.log(maxValue(arr));

//Driver Code Ends

Output
5

[Better Approach - 1 ] Using Top-Down DP (Memoization) - O(n) Time and O(n) Space

In the recursive solution, there are many overlapping subproblems because the same states are solved multiple times.
To avoid this repetition, we can use memoization where we store the results of already computed subproblems in a separate array (memo). Before solving any subproblem, we first check in the memo[i] if it has been computed earlier. If yes, we simply reuse the stored result instead of recalculating it.

C++
//Driver Code Starts
#include <iostream>
#include <vector>
using namespace std;
//Driver Code Ends


// Calculate the maximum stolen value recursively
int maxValRec(vector<int> &arr, int i, int j, vector<int> &memo) {
    
    // If no houses are left, return 0.
    if (i> j)  return 0;
  
      // If only 1 house is left, rob it. 
    if (i == j)  return arr[i];
    
    // If value is memoized
    if (memo[j] != -1) return memo[j];

    // Two Choices: 
    // Rob the jth house and skip the (j-1)th house 
    int pick = arr[j] + maxValRec(arr, i, j-2, memo);
    
    // Skip the jth house
    int notPick = maxValRec(arr, i, j-1, memo);

    // Return the max of two choices
    return memo[j] = max(pick, notPick);
}

// Function to calculate the maximum stolen value
int maxValue(vector<int>& arr) {
    int n = arr.size();
  
    int ans = 0;
    
    vector<int> memo(n, -1);
    
    // Skip the last house
    ans = max(ans, maxValRec(arr, 0, n-2, memo));
    
    // Reset the memo array
    for (int i=0; i<n; i++) memo[i] = -1;
    
    // Skip the first house 
    ans = max(ans, maxValRec(arr, 1, n-1, memo));
    
    return ans;
}


//Driver Code Starts
int main() {
    vector<int> arr = {2, 2, 3, 1, 2};
    cout << maxValue(arr);
    return 0;
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.Arrays;

class GfG {
//Driver Code Ends


    // Calculate the maximum stolen value recursively
    static int maxValRec(int[] arr, int i, int j, int[] memo) {
        
        // If no houses are left, return 0.
        if (i > j) return 0;
    
        // If only 1 house is left, rob it. 
        if (i == j) return arr[i];

        // If value is memoized
        if (memo[j] != -1) return memo[j];

        // Two Choices: 
        // Rob the jth house and skip the (j-1)th house 
        int pick = arr[j] + maxValRec(arr, i, j - 2, memo);
        
        // Skip the jth house
        int notPick = maxValRec(arr, i, j - 1, memo);

        // Return the max of two choices
        return memo[j] = Math.max(pick, notPick);
    }

    // Function to calculate the maximum stolen value
    static int maxValue(int[] arr) {
        int n = arr.length;
    
        int ans = 0;
        
        int[] memo = new int[n];
        Arrays.fill(memo, -1);
        
        // Skip the last house
        ans = Math.max(ans, maxValRec(arr, 0, n - 2, memo));
        
        // Reset the memo array
        Arrays.fill(memo, -1);
        
        // Skip the first house 
        ans = Math.max(ans, maxValRec(arr, 1, n - 1, memo));
        
        return ans;
    }


//Driver Code Starts
    public static void main(String[] args) {
        int[] arr = {2, 2, 3, 1, 2};
        System.out.println(maxValue(arr));
    }
}

//Driver Code Ends
Python
# Calculate the maximum stolen value recursively
def maxValRec(arr, i, j, memo):
    
    # If no houses are left, return 0.
    if i > j:
        return 0

    # If only 1 house is left, rob it. 
    if i == j:
        return arr[i]

    # If value is memoized
    if memo[j] != -1:
        return memo[j]

    # Two Choices: 
    # Rob the jth house and skip the (j-1)th house 
    pick = arr[j] + maxValRec(arr, i, j - 2, memo)
    
    # Skip the jth house
    notPick = maxValRec(arr, i, j - 1, memo)

    # Return the max of two choices
    memo[j] = max(pick, notPick)
    return memo[j]

# Function to calculate the maximum stolen value
def maxValue(arr):
    n = len(arr)

    ans = 0
    
    memo = [-1] * n
    
    # Skip the last house
    ans = max(ans, maxValRec(arr, 0, n - 2, memo))
    
    # Reset the memo array
    memo = [-1] * n
    
    # Skip the first house 
    ans = max(ans, maxValRec(arr, 1, n - 1, memo))
    
    return ans


if __name__ == "__main__":
#Driver Code Starts
    arr = [2, 2, 3, 1, 2]
    print(maxValue(arr))

#Driver Code Ends
C#
//Driver Code Starts
using System;

class GfG {
//Driver Code Ends


    // Calculate the maximum stolen value recursively
    static int maxValRec(int[] arr, int i, int j, int[] memo) {
        
        // If no houses are left, return 0.
        if (i > j) return 0;
    
        // If only 1 house is left, rob it. 
        if (i == j) return arr[i];

        // If value is memoized
        if (memo[j] != -1) return memo[j];

        // Two Choices: 
        // Rob the jth house and skip the (j-1)th house 
        int pick = arr[j] + maxValRec(arr, i, j - 2, memo);
        
        // Skip the jth house
        int notPick = maxValRec(arr, i, j - 1, memo);

        // Return the max of two choices
        return memo[j] = Math.Max(pick, notPick);
    }

    // Function to calculate the maximum stolen value
    static int maxValue(int[] arr) {
        int n = arr.Length;

        int ans = 0;
        
        int[] memo = new int[n];
        Array.Fill(memo, -1);
        
        // Skip the last house
        ans = Math.Max(ans, maxValRec(arr, 0, n - 2, memo));
        
        // Reset the memo array
        Array.Fill(memo, -1);
        
        // Skip the first house 
        ans = Math.Max(ans, maxValRec(arr, 1, n - 1, memo));
        
        return ans;
    }


//Driver Code Starts
    static void Main() {
        int[] arr = {2, 2, 3, 1, 2};
        Console.WriteLine(maxValue(arr));
    }
}

//Driver Code Ends
JavaScript
// Calculate the maximum stolen value recursively
function maxValRec(arr, i, j, memo) {
    
    // If no houses are left, return 0.
    if (i > j) return 0;

    // If only 1 house is left, rob it. 
    if (i == j) return arr[i];

    // If value is memoized
    if (memo[j] !== -1) return memo[j];

    // Two Choices: 
    // Rob the jth house and skip the (j-1)th house 
    let pick = arr[j] + maxValRec(arr, i, j - 2, memo);
    
    // Skip the jth house
    let notPick = maxValRec(arr, i, j - 1, memo);

    // Return the max of two choices
    memo[j] = Math.max(pick, notPick);
    return memo[j];
}

// Function to calculate the maximum stolen value
function maxValue(arr) {
    let n = arr.length;

    let ans = 0;
    
    let memo = new Array(n).fill(-1);
    
    // Skip the last house
    ans = Math.max(ans, maxValRec(arr, 0, n - 2, memo));
    
    // Reset the memo array
    memo.fill(-1);
    
    // Skip the first house 
    ans = Math.max(ans, maxValRec(arr, 1, n - 1, memo));
    
    return ans;
}


//Driver Code
//Driver Code Starts
let arr = [2, 2, 3, 1, 2];
console.log(maxValue(arr));

//Driver Code Ends

Output
5

[Better Approach - 2] Using Bottom-Up DP (Tabulation) - O(n) Time and O(n) Space

The main idea is to build the solution iteratively using a DP table where each entry represents the maximum money that can be stolen up to that house.

The relation that helps us compute this is: dp[j] = max(arr[j] + dp[j-2], dp[j-1])
This ensures we always choose the option that gives the maximum total amount without robbing two adjacent houses.

The formula dp[j] = max(arr[j] + dp[j−2], dp[j−1]) comes from two choices:

  • The thief robs the current house then skips the previous one, so total becomes arr[j] + dp[j−2].
  • The thief skips the current house → and takes the maximum money till the previous house, i.e. dp[j−1].

We take the maximum of these two options to ensure the thief always gets the highest possible amount.

C++
//Driver Code Starts
#include <iostream>
#include <vector>
using namespace std;
//Driver Code Ends


// Tabulation approach to find the maximum 
// value. 
int maxValTab(int x, int y, vector<int> &arr) {
    int n = arr.size();
    if (n == 2) return max(arr[0], arr[1]);
    vector<int> dp(n);
    
    // For first house, taking is only option
    dp[x] = arr[x];
    
    // For second house, we can either take
    // from 1st or 2nd.
    dp[x+1] = max(arr[x], arr[x+1]);
    
    for (int j=x+2; j<=y; j++) {
        int take = arr[j] + dp[j-2];
        int noTake = dp[j-1];
        
        dp[j] = max(take, noTake);
    }
    
    return dp[y];
}

// Function to calculate the maximum stolen value
int maxValue(vector<int>& arr) {
    int n = arr.size();
    
    // Base cases
    if (n == 0) return 0;
    if (n == 1) return arr[0];
  
    int ans = 0;
    
    // Skipping last house 
    ans = max(ans, maxValTab(0, n-2, arr));
    
    // Skipping first house 
    ans = max(ans, maxValTab(1, n-1, arr));
    
    return ans;
}


//Driver Code Starts
int main() {
    vector<int> arr = {2, 2, 3, 1, 2};
    cout << maxValue(arr);
    return 0;
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.Arrays;

class GfG {
//Driver Code Ends


    // Tabulation approach to find the maximum 
    // value.
    static int maxValTab(int x, int y, int[] arr) {
        int n = arr.length;
        if (n == 2) return Math.max(arr[0], arr[1]);
        int[] dp = new int[n];
        
        // For first house, taking is only option
        dp[x] = arr[x];
        
        // For second house, we can either take
        // from 1st or 2nd.
        dp[x+1] = Math.max(arr[x], arr[x+1]);
        
        for (int j = x + 2; j <= y; j++) {
            int take = arr[j] + dp[j - 2];
            int noTake = dp[j - 1];
            
            dp[j] = Math.max(take, noTake);
        }
        
        return dp[y];
    }

    // Function to calculate the maximum stolen value
    static int maxValue(int[] arr) {
        int n = arr.length;
        
        // Base cases
        if (n == 0) return 0;
        if (n == 1) return arr[0];
    
        int ans = 0;
        
        // Skipping last house 
        ans = Math.max(ans, maxValTab(0, n - 2, arr));
        
        // Skipping first house 
        ans = Math.max(ans, maxValTab(1, n - 1, arr));
        
        return ans;
    }


//Driver Code Starts
    public static void main(String[] args) {
        int[] arr = {2, 2, 3, 1, 2};
        System.out.println(maxValue(arr));
    }
}

//Driver Code Ends
Python
# Tabulation approach to find the maximum 
# value. 
def maxValTab(x, y, arr):
    n = len(arr)
    if n == 2:
        return max(arr[0], arr[1])
    dp = [0] * n
    
    # For first house, taking is only option
    dp[x] = arr[x]
    
    # For second house, we can either take
    # from 1st or 2nd.
    dp[x+1] = max(arr[x], arr[x+1])
    
    for j in range(x + 2, y + 1):
        take = arr[j] + dp[j - 2]
        noTake = dp[j - 1]
        
        dp[j] = max(take, noTake)
    
    return dp[y]

# Function to calculate the maximum stolen value
def maxValue(arr):
    n = len(arr)
    
    # Base cases
    if n == 0:
        return 0
    if n == 1:
        return arr[0]

    ans = 0
    
    # Skipping last house 
    ans = max(ans, maxValTab(0, n - 2, arr))
    
    # Skipping first house 
    ans = max(ans, maxValTab(1, n - 1, arr))
    
    return ans


if __name__ == "__main__":
#Driver Code Starts
    arr = [2, 2, 3, 1, 2]
    print(maxValue(arr))

#Driver Code Ends
C#
//Driver Code Starts
using System;

class GfG {
//Driver Code Ends


    // Tabulation approach to find the maximum 
    // value
    static int maxValTab(int x, int y, int[] arr) {
        int n = arr.Length;
        if (n == 2) return Math.Max(arr[0], arr[1]);
        int[] dp = new int[n];
        
        // For first house, taking is only option
        dp[x] = arr[x];
        
        // For second house, we can either take
        // from 1st or 2nd.
        dp[x+1] = Math.Max(arr[x], arr[x+1]);
        
        for (int j = x + 2; j <= y; j++) {
            int take = arr[j] + dp[j - 2];
            int noTake = dp[j - 1];
            
            dp[j] = Math.Max(take, noTake);
        }
        
        return dp[y];
    }

    // Function to calculate the maximum stolen value
    static int maxValue(int[] arr) {
        int n = arr.Length;
        
        // Base cases
        if (n == 0) return 0;
        if (n == 1) return arr[0];
    
        int ans = 0;
        
        // Skipping last house 
        ans = Math.Max(ans, maxValTab(0, n - 2, arr));
        
        // Skipping first house 
        ans = Math.Max(ans, maxValTab(1, n - 1, arr));
        
        return ans;
    }


//Driver Code Starts
    static void Main() {
        int[] arr = {2, 2, 3, 1, 2};
        Console.WriteLine(maxValue(arr));
    }
}

//Driver Code Ends
JavaScript
// Tabulation approach to find the maximum 
// value.
function maxValTab(x, y, arr) {
    let n = arr.length;
    if (n === 2) return Math.max(arr[0], arr[1]);
    let dp = new Array(n).fill(0);
    
    // For first house, taking is only option
    dp[x] = arr[x];
    
    // For second house, we can either take
    // from 1st or 2nd.
    dp[x + 1] = Math.max(arr[x], arr[x + 1]);
    
    for (let j = x + 2; j <= y; j++) {
        let take = arr[j] + dp[j - 2];
        let noTake = dp[j - 1];
        
        dp[j] = Math.max(take, noTake);
    }
    
    return dp[y];
}

// Function to calculate the maximum stolen value
function maxValue(arr) {
    let n = arr.length;
    
    // Base cases
    if (n === 0) return 0;
    if (n === 1) return arr[0];

    let ans = 0;
    
    // Skipping last house 
    ans = Math.max(ans, maxValTab(0, n - 2, arr));
    
    // Skipping first house 
    ans = Math.max(ans, maxValTab(1, n - 1, arr));
    
    return ans;
}

//Driver Code
//Driver Code Starts
let arr = [2, 2, 3, 1, 2];
console.log(maxValue(arr));

//Driver Code Ends

Output
5

[Expected Approach ] Using Space Optimized DP - O(n) Time and O(1) Space

In the previous approach, we used an array to store results for all states. However, if we look closely, to calculate the result for the current house, we only need the values from the previous two houses.This means there’s no need to store all previous results.
We can simply keep track of the last two computed values and update them as we move forward.

C++
//Driver Code Starts
#include <iostream>
#include <vector>
using namespace std;
//Driver Code Ends


// Tabulation approach to find the maximum 
// value.
int maxValTab(int x, int y, vector<int> &arr) {
    int n = arr.size();
     if (n == 2) return max(arr[0], arr[1]);
    // For first house, taking is only option
    int prev2 = arr[x];
    
    // For second house, we can either take
    // from 1st or 2nd.
    int prev1 = max(arr[x], arr[x+1]);
    
    for (int j=x+2; j<=y; j++) {
        int take = arr[j] + prev2;
        int noTake = prev1;
        
        int curr = max(take, noTake);
        
        // update states
        prev2 = prev1;
        prev1 = curr;
    }
    
    return prev1;
}

// Function to calculate the maximum stolen value
int maxValue(vector<int>& arr) {
    int n = arr.size();
    
    // Base cases
    if (n == 0) return 0;
    if (n == 1) return arr[0];
  
    int ans = 0;
    
    // Skipping last house 
    ans = max(ans, maxValTab(0, n-2, arr));
    
    // Skipping first house 
    ans = max(ans, maxValTab(1, n-1, arr));
    
    return ans;
}


//Driver Code Starts
int main() {
    vector<int> arr = {2, 2, 3, 1, 2};
    cout << maxValue(arr);
    return 0;
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.Arrays;

class GfG {
//Driver Code Ends


    // Tabulation approach to find the maximum 
    // value.
    static int maxValTab(int x, int y, int[] arr) {
        int n = arr.length;
        if (n == 2) return Math.max(arr[0], arr[1]);
        // For first house, taking is only option
        int prev2 = arr[x];
        
        // For second house, we can either take
        // from 1st or 2nd.
        int prev1 = Math.max(arr[x], arr[x + 1]);
        
        for (int j = x + 2; j <= y; j++) {
            int take = arr[j] + prev2;
            int noTake = prev1;
            
            int curr = Math.max(take, noTake);
            
            // update states
            prev2 = prev1;
            prev1 = curr;
        }
        
        return prev1;
    }

    // Function to calculate the maximum stolen value
    static int maxValue(int[] arr) {
        int n = arr.length;
        
        // Base cases
        if (n == 0) return 0;
        if (n == 1) return arr[0];
    
        int ans = 0;
        
        // Skipping last house 
        ans = Math.max(ans, maxValTab(0, n - 2, arr));
        
        // Skipping first house 
        ans = Math.max(ans, maxValTab(1, n - 1, arr));
        
        return ans;
    }


//Driver Code Starts
    public static void main(String[] args) {
        int[] arr = {2, 2, 3, 1, 2};
        System.out.println(maxValue(arr));
    }
}

//Driver Code Ends
Python
 # Tabulation approach to find the maximum 
#value.
def maxValTab(x, y, arr):
    n = len(arr)
    if n == 2:
        return max(arr[0], arr[1])
    # For first house, taking is only option
    prev2 = arr[x]
    
    # For second house, we can either take
    # from 1st or 2nd.
    prev1 = max(arr[x], arr[x + 1])
    
    for j in range(x + 2, y + 1):
        take = arr[j] + prev2
        noTake = prev1
        
        curr = max(take, noTake)
        
        # update states
        prev2 = prev1
        prev1 = curr
    
    return prev1

# Function to calculate the maximum stolen value
def maxValue(arr):
    n = len(arr)
    
    # Base cases
    if n == 0:
        return 0
    if n == 1:
        return arr[0]

    ans = 0
    
    # Skipping last house 
    ans = max(ans, maxValTab(0, n - 2, arr))
    
    # Skipping first house 
    ans = max(ans, maxValTab(1, n - 1, arr))
    
    return ans


#Driver Code Starts
if __name__ == "__main__":
    arr = [2, 2, 3, 1, 2]
    print(maxValue(arr))

#Driver Code Ends
C#
//Driver Code Starts
using System;

class GfG {
//Driver Code Ends

    
    // Tabulation approach to find the maximum 
    // value. 
    static int maxValTab(int x, int y, int[] arr) {
        int n = arr.Length;
        if (n == 2) return Math.Max(arr[0], arr[1]);
        // For first house, taking is only option
        int prev2 = arr[x];
        
        // For second house, we can either take
        // from 1st or 2nd.
        int prev1 = Math.Max(arr[x], arr[x + 1]);
        
        for (int j = x + 2; j <= y; j++) {
            int take = arr[j] + prev2;
            int noTake = prev1;
            
            int curr = Math.Max(take, noTake);
            
            // update states
            prev2 = prev1;
            prev1 = curr;
        }
        
        return prev1;
    }

    // Function to calculate the maximum stolen value
    static int maxValue(int[] arr) {
        int n = arr.Length;
        
        // Base cases
        if (n == 0) return 0;
        if (n == 1) return arr[0];
    
        int ans = 0;
        
        // Skipping last house 
        ans = Math.Max(ans, maxValTab(0, n - 2, arr));
        
        // Skipping first house 
        ans = Math.Max(ans, maxValTab(1, n - 1, arr));
        
        return ans;
    }


//Driver Code Starts
    static void Main(string[] args) {
        int[] arr = {2, 2, 3, 1, 2};
        Console.WriteLine(maxValue(arr));
    }
}

//Driver Code Ends
JavaScript
// Tabulation approach to find the maximum 
// value.
function maxValTab(x, y, arr) {
    let n = arr.length;
    if (n === 2) return Math.max(arr[0], arr[1]);
    // For first house, taking is only option
    let prev2 = arr[x];
    
    // For second house, we can either take
    // from 1st or 2nd.
    let prev1 = Math.max(arr[x], arr[x + 1]);
    
    for (let j = x + 2; j <= y; j++) {
        let take = arr[j] + prev2;
        let noTake = prev1;
        
        let curr = Math.max(take, noTake);
        
        // update states
        prev2 = prev1;
        prev1 = curr;
    }
    
    return prev1;
}

// Function to calculate the maximum stolen value
function maxValue(arr) {
    let n = arr.length;
    
    // Base cases
    if (n === 0) return 0;
    if (n === 1) return arr[0];

    let ans = 0;
    
    // Skipping last house 
    ans = Math.max(ans, maxValTab(0, n - 2, arr));
    
    // Skipping first house 
    ans = Math.max(ans, maxValTab(1, n - 1, arr));
    
    return ans;
}


//Driver Code
//Driver Code Starts
let arr = [2, 2, 3, 1, 2];
console.log(maxValue(arr));

//Driver Code Ends

Output
5
    Comment