Taro Logo

Maximum Ascending Subarray Sum

Easy
Amazon logo
Amazon
Topics:
ArraysDynamic Programming

Given an array of positive integers nums, return the maximum possible sum of a strictly increasing subarray in nums.

A subarray is defined as a contiguous sequence of numbers in an array.

Example 1:

Input: nums = [10,20,30,5,10,50]
Output: 65
Explanation: [5,10,50] is the ascending subarray with the maximum sum of 65.

Example 2:

Input: nums = [10,20,30,40,50]
Output: 150
Explanation: [10,20,30,40,50] is the ascending subarray with the maximum sum of 150.

Example 3:

Input: nums = [12,17,15,13,10,11,12]
Output: 33
Explanation: [10,11,12] is the ascending subarray with the maximum sum of 33.

Constraints:

  • 1 <= nums.length <= 100
  • 1 <= nums[i] <= 100

Solution


Naive Solution (Brute Force)

The most straightforward approach is to generate all possible subarrays, check if each subarray is strictly increasing, and compute the sum of those that satisfy the condition. Keep track of the maximum sum found so far.

def max_increasing_subarray_sum_brute_force(nums):
    max_sum = 0
    n = len(nums)
    for i in range(n):
        for j in range(i, n):
            subarray = nums[i:j+1]
            if is_strictly_increasing(subarray):
                max_sum = max(max_sum, sum(subarray))
    return max_sum


def is_strictly_increasing(arr):
    if len(arr) <= 1:
        return True
    for i in range(1, len(arr)):
        if arr[i] <= arr[i-1]:
            return False
    return True

Big O Runtime: O(n^3) because we iterate through all possible subarrays O(n^2) and then check if each one is strictly increasing in O(n) time.

Big O Space Usage: O(n) in the worst case, due to the subarray created.

Optimal Solution (Dynamic Programming)

We can solve this problem more efficiently using dynamic programming. We can maintain a dp array where dp[i] represents the maximum sum of a strictly increasing subarray ending at index i. If nums[i] > nums[i-1], then we can extend the previous subarray, so dp[i] = dp[i-1] + nums[i]. Otherwise, we start a new subarray with just nums[i]. We keep track of the overall maximum sum as we go.

def max_increasing_subarray_sum_dp(nums):
    n = len(nums)
    dp = [0] * n
    max_sum = nums[0]
    dp[0] = nums[0]

    for i in range(1, n):
        if nums[i] > nums[i-1]:
            dp[i] = dp[i-1] + nums[i]
        else:
            dp[i] = nums[i]
        max_sum = max(max_sum, dp[i])

    return max_sum

Big O Runtime: O(n), because we iterate through the array once.

Big O Space Usage: O(n), due to the dp array. This can be optimized to O(1) by keeping track of only the previous sum instead of storing the sums for all indices.

Optimized Space (O(1))

def max_increasing_subarray_sum_optimized(nums):
    n = len(nums)
    max_sum = nums[0]
    current_sum = nums[0]

    for i in range(1, n):
        if nums[i] > nums[i-1]:
            current_sum += nums[i]
        else:
            current_sum = nums[i]
        max_sum = max(max_sum, current_sum)

    return max_sum

Edge Cases:

  • Empty Array: If the input array is empty, the maximum sum should be 0.
  • Single Element Array: If the input array has only one element, the maximum sum is that element itself.
  • Array with decreasing elements: The algorithm will still find the maximum single element in this case.
  • Array with equal elements: The algorithm will correctly identify each element as a new subarray and return the maximum element.