Maximum sum in circular array such that no two elements are adjacent (original) (raw)
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 orarr[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.
Table of Content
- [Naive Approach ] Using Recursion - O(2^n) Time and O(n) Space
- [Better Approach - 1 ] Using Top-Down DP (Memoization) - O(n) Time and O(n) Space
- [Better Approach - 2 ] Using Bottom-Up DP (Tabulation) - O(n) Time and O(n) Space
- [Expected Approach ] Using Space Optimized DP - O(n) Time and O(1) Space
[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 #include using namespace std; //Driver Code Ends
// Calculate the maximum stolen value recursively int maxValRec(vector &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& 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 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 ansif 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
`
[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 #include using namespace std; //Driver Code Ends
// Calculate the maximum stolen value recursively int maxValRec(vector &arr, int i, int j, vector &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& 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 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 ansif 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
`
[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 #include using namespace std; //Driver Code Ends
// Tabulation approach to find the maximum // value. int maxValTab(int x, int y, vector &arr) { int n = arr.size(); if (n == 2) return max(arr[0], arr[1]); vector 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& 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 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 ansif 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
`
[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 #include using namespace std; //Driver Code Ends
// Tabulation approach to find the maximum // value. int maxValTab(int x, int y, vector &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& 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 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 prev1Function 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
`