Problem Statement (Asked By Airbnb)
Given a list of integers, write a function to compute the largest sum of numbers such that no two numbers are adjacent in the list. The input may contain zero or negative values.
For example, [2, 4, 6, 2, 5]
should return 13
, since we pick 2
, 6
, and 5
. [5, 1, 1, 5]
should return 10
, since we pick 5
and 5
.
Can you optimize your solution to run in O(N) time and use constant space?
Problem link: https://leetcode.com/problems/count-univalue-subtrees/description/
Disclaimer: Try solving the problem on your own first! Use this solution only as a reference to learn and improve.
This problem appears straightforward initially but contains some complexities. A greedy approach like picking the largest number, then the next largest non-adjacent number, and so on, doesn’t work consistently due to edge cases.
Instead, we can solve this problem recursively. Suppose we have a function that already computes the maximum sum of non-adjacent numbers for smaller arrays. Using this, we can decide between two cases:
Thus, the solution can be expressed as:
max(a[1:],a[0]+a[2:])
public class LargestNonAdjacentSum { public static int largestNonAdjacent(int[] arr) { if (arr == null || arr.length == 0) { return 0; } if (arr.length == 1) { return Math.max(0, arr[0]); } return Math.max( largestNonAdjacent(java.util.Arrays.copyOfRange(arr, 1, arr.length)), arr[0] + largestNonAdjacent(java.util.Arrays.copyOfRange(arr, 2, arr.length)) ); } public static void main(String[] args) { int[] arr = {3, 2, 5, 10, 7}; System.out.println("Max Sum: " + largestNonAdjacent(arr)); // Output: 15 } }
This recursive solution works but is highly inefficient due to redundant calculations.
We can use dynamic programming to avoid redundant calculations by storing the maximum sum of non-adjacent numbers up to each index in a cache.
public class LargestNonAdjacentSum { public static int largestNonAdjacent(int[] arr) { if (arr == null || arr.length == 0) { return 0; } if (arr.length == 1) { return Math.max(0, arr[0]); } int[] cache = new int[arr.length]; cache[0] = Math.max(0, arr[0]); cache[1] = Math.max(cache[0], arr[1]); for (int i = 2; i < arr.length; i++) { cache[i] = Math.max(arr[i] + cache[i - 2], cache[i - 1]); } return cache[arr.length - 1]; } public static void main(String[] args) { int[] arr = {3, 2, 5, 10, 7}; System.out.println("Max Sum: " + largestNonAdjacent(arr)); // Output: 15 } }
This solution runs in O(n) time but uses O(n) space.
Since we only need the last two values of the cache at any point, we can reduce the space complexity to O(1).
public class LargestNonAdjacentSum { public static int largestNonAdjacent(int[] arr) { if (arr == null || arr.length == 0) { return 0; } if (arr.length == 1) { return Math.max(0, arr[0]); } int maxExcludingLast = Math.max(0, arr[0]); int maxIncludingLast = Math.max(maxExcludingLast, arr[1]); for (int i = 2; i < arr.length; i++) { int current = Math.max(maxIncludingLast, maxExcludingLast + arr[i]); maxExcludingLast = maxIncludingLast; maxIncludingLast = current; } return maxIncludingLast; } public static void main(String[] args) { int[] arr = {3, 2, 5, 10, 7}; System.out.println("Max Sum: " + largestNonAdjacent(arr)); // Output: 15 } }
maxExcludingLast
: Stores the maximum sum excluding the current element.maxIncludingLast
: Stores the maximum sum including the current element.maxIncludingLast=max(maxIncludingLast,maxExcludingLast+current element)
Time Complexity: O(n)
Space Complexity: O(1)
Did this solution help you understand the concept better? Let me know your thoughts in the comments below! Don’t forget to follow us on Instagram @coderz.py for more DSA tips and solutions to ace your coding interviews.
Find the length of the longest absolute path to a file within the abstracted file…
You manage an e-commerce website and need to keep track of the last N order…
You are given a stream of elements that is too large to fit into memory.…
The formula for the area of a circle is given by πr². Use the Monte…
Given an integer k and a string s, write a function to determine the length…
There is a staircase with N steps, and you can ascend either 1 step or…