Taro Logo

Maximum Sum of Subsequence With Non-adjacent Elements

Hard
Meta logo
Meta
1 view
Topics:
ArraysDynamic Programming

You are given an array nums consisting of integers. You are also given a 2D array queries, where queries[i] = [pos_i, x_i]. For query i, you first set nums[pos_i] equal to x_i, then you calculate the answer to query i which is the maximum sum of a subsequence of nums where no two adjacent elements are selected. Return the sum of the answers to all queries modulo 10^9 + 7. A subsequence is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements.

For example:

nums = [3,5,9], queries = [[1,-2],[0,-3]]

After the 1st query, nums = [3,-2,9] and the maximum sum of a subsequence with non-adjacent elements is 3 + 9 = 12.

After the 2nd query, nums = [-3,-2,9] and the maximum sum of a subsequence with non-adjacent elements is 9.

Therefore, the answer is 12 + 9 = 21.

As another example:

nums = [0,-1], queries = [[0,-5]]

After the 1st query, nums = [-5,-1] and the maximum sum of a subsequence with non-adjacent elements is 0 (choosing an empty subsequence).

Therefore, the answer is 0. How would you efficiently solve this problem?

Solution


Naive Approach

A brute-force approach would involve, for each query, updating the nums array and then iterating through all possible subsequences to find the one with the maximum sum where no two adjacent elements are selected. This involves generating all possible subsequences, which takes exponential time.

Code (Python)

def max_non_adjacent_subsequence_sum(arr):
    n = len(arr)
    max_sum = 0
    for i in range(1 << n):
        subsequence = []
        for j in range(n):
            if (i >> j) & 1:
                subsequence.append(arr[j])

        valid = True
        for k in range(len(subsequence) - 1):
            if arr.index(subsequence[k]) + 1 == arr.index(subsequence[k+1]):
                valid = False
                break

        if valid:
            max_sum = max(max_sum, sum(subsequence))
    return max_sum

def solve_queries_brute_force(nums, queries):
    total_sum = 0
    for pos, x in queries:
        original_value = nums[pos]
        nums[pos] = x
        total_sum += max_non_adjacent_subsequence_sum(nums)
        nums[pos] = original_value  # Backtrack
    return total_sum
  • Time Complexity: O(q * 2n * n), where q is the number of queries and n is the length of the array.
  • Space Complexity: O(n), due to the subsequence list.

This brute-force approach is highly inefficient and will not pass test cases with larger constraints.

Optimal Approach

A dynamic programming approach can efficiently solve the maximum non-adjacent subsequence sum problem. For each query, we update the array and then apply dynamic programming to find the maximum sum.

Let dp[i] be the maximum sum of a subsequence ending at index i such that no two elements are adjacent. Then,

dp[i] = max(dp[i-1], nums[i] + dp[i-2])

Here, dp[i-1] represents the case where we don't include nums[i] in the subsequence, and nums[i] + dp[i-2] represents the case where we include nums[i] (and therefore cannot include nums[i-1]). The base cases are dp[0] = max(0, nums[0]) and dp[1] = max(nums[0], nums[1], 0).

Code (Python)

def max_non_adjacent_sum_dp(nums):
    n = len(nums)
    if n == 0:
        return 0
    if n == 1:
        return max(0, nums[0])

    dp = [0] * n
    dp[0] = max(0, nums[0])
    dp[1] = max(dp[0], nums[1], 0)

    for i in range(2, n):
        dp[i] = max(dp[i-1], nums[i] + dp[i-2])

    return dp[n-1]

def solve_queries_optimal(nums, queries):
    total_sum = 0
    mod = 10**9 + 7
    for pos, x in queries:
        original_value = nums[pos]
        nums[pos] = x
        total_sum = (total_sum + max_non_adjacent_sum_dp(nums)) % mod
        nums[pos] = original_value  # Backtrack
    return total_sum
  • Time Complexity: O(q * n), where q is the number of queries and n is the length of the array. For each query, we iterate through the array once to apply dynamic programming.
  • Space Complexity: O(n), due to the dp array.

Edge Cases:

  • Empty array: Handle the case where the input array is empty. The maximum sum is 0.
  • Array with one element: The maximum sum is the maximum of 0 and the element itself.
  • Negative numbers: The algorithm should correctly handle negative numbers by potentially choosing an empty subsequence (sum 0) if all possible subsequences yield negative sums.