Program to find largest sum of non-adjacent elements of a list in Python

The problem of finding the largest sum of non-adjacent elements in a list is a classic dynamic programming problem. Given a list of numbers, we need to select elements such that no two selected elements are adjacent, and their sum is maximized.

So, if the input is like [3, 5, 7, 3, 6], then the output will be 16, as we can take 3, 7, and 6 to get the maximum sum without selecting adjacent elements.

Algorithm Approach

We use dynamic programming with two variables to track the maximum sum:

  • take: Maximum sum including the current element

  • noTake: Maximum sum excluding the current element

For each element, we decide whether to include it or not based on which choice gives the maximum sum.

Implementation

def find_max_sum_non_adjacent(nums):
    if len(nums) <= 2:
        return max(nums) if nums else 0
    
    noTake = 0
    take = nums[0]
    
    for i in range(1, len(nums)):
        # Current element can be taken with previous noTake sum
        # Or we can skip current element and keep previous max
        take, noTake = noTake + nums[i], max(noTake, take)
    
    return max(noTake, take)

# Test with example
nums = [3, 5, 7, 3, 6]
result = find_max_sum_non_adjacent(nums)
print(f"Maximum sum of non-adjacent elements: {result}")
Maximum sum of non-adjacent elements: 16

How It Works

Let's trace through the algorithm with [3, 5, 7, 3, 6]:

def find_max_sum_detailed(nums):
    if len(nums) <= 2:
        return max(nums) if nums else 0
    
    noTake = 0
    take = nums[0]
    print(f"Initial: take={take}, noTake={noTake}")
    
    for i in range(1, len(nums)):
        old_take, old_noTake = take, noTake
        take = noTake + nums[i]
        noTake = max(old_noTake, old_take)
        print(f"i={i}, nums[i]={nums[i]}: take={take}, noTake={noTake}")
    
    return max(noTake, take)

nums = [3, 5, 7, 3, 6]
result = find_max_sum_detailed(nums)
print(f"Final result: {result}")
Initial: take=3, noTake=0
i=1, nums[i]=5: take=5, noTake=3
i=2, nums[i]=7: take=10, noTake=5
i=3, nums[i]=3: take=8, noTake=10
i=4, nums[i]=6: take=16, noTake=10
Final result: 16

Testing with Different Cases

def test_cases():
    test_data = [
        ([3, 5, 7, 3, 6], 16),
        ([1, 2, 3], 4),
        ([5, 1, 3, 9], 14),
        ([2, 1], 2),
        ([0, -1, 2], 2),
        ([10], 10)
    ]
    
    for nums, expected in test_data:
        result = find_max_sum_non_adjacent(nums)
        status = "?" if result == expected else "?"
        print(f"{status} {nums} ? {result} (expected: {expected})")

test_cases()
? [3, 5, 7, 3, 6] ? 16 (expected: 16)
? [1, 2, 3] ? 4 (expected: 4)
? [5, 1, 3, 9] ? 14 (expected: 14)
? [2, 1] ? 2 (expected: 2)
? [0, -1, 2] ? 2 (expected: 2)
? [10] ? 10 (expected: 10)

Time and Space Complexity

  • Time Complexity: O(n) - single pass through the array

  • Space Complexity: O(1) - only two variables used

Conclusion

This dynamic programming solution efficiently finds the maximum sum of non-adjacent elements using constant space. The key insight is maintaining two states: taking or not taking the current element, and choosing the optimal decision at each step.

Updated on: 2026-03-25T11:15:17+05:30

946 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements