Problem Description
Given an array of integers nums, we call a subsequence (not necessarily contiguous, but with preserved order) “consecutive” if the difference between every two adjacent elements is either always +1 or always –1. (Note that a single-element array is considered consecutive.) The value of an array is defined as the sum of its elements. Your goal is to return the sum of the values of all consecutive non-empty subsequences of nums modulo 10^9 + 7.
For example, for nums = [1,2] the valid consecutive subsequences are [1], [2], and [1,2] with total value 1 + 2 + (1+2) = 6. For nums = [1,4,2,3] the valid subsequences are [1], [4], [2], [3], [1,2], [2,3], [4,3] and [1,2,3] which sum to 31.
Key Insights
- A valid subsequence (respecting original order) is one where adjacent elements differ by exactly +1 (increasing) or –1 (decreasing).
- Every individual element (singleton) is trivially consecutive.
- Directly enumerating subsequences is infeasible because there can be exponentially many; hence we use dynamic programming.
- We can maintain two DP states—one for subsequences following an increasing pattern and one for those following a decreasing pattern.
- When processing an element, it can start a new subsequence or extend a previously built subsequence if the required previous value exists.
- For extension, if we already have some subsequences ending with (current - 1) for increasing (or (current + 1) for decreasing), then we create new subsequences by appending the current element. Their contribution to the "subsequence value" equals the previous total sum plus the current element multiplied by the count of sequences extended.
- Since single-element subsequences appear in both cases (increasing and decreasing) and must be counted only once, we subtract one copy of the new element’s value when combining the two states.
Space and Time Complexity
Time Complexity: O(n) – We process each element once while updating and looking up in hash maps. Space Complexity: O(m) – Where m is the number of distinct nums values encountered (at most 10^5).
Solution
We iterate over nums in order. For each element x, we compute two “DP” values:
- For increasing subsequences (difference +1): Start a new subsequence with x, and if there are subsequences ending with x–1 already (stored in a dictionary dp_inc), extend each of them to now end with x. For an extension, if there are c subsequences ending with x–1 summing to S, the new contribution when extended with x is S + c*x.
- For decreasing subsequences (difference –1): Similarly, start a new subsequence and extend any subsequences ending with x+1 from a dictionary dp_dec.
- Since a singleton [x] is created in both increasing and decreasing cases, we subtract x once to avoid double counting.
- We add the contribution (sum) from new subsequences (increasing + decreasing, adjusted) to our final result and update dp_inc[x] and dp_dec[x] for use in subsequent extensions.
Each dp dictionary stores a pair:
- count: number of valid subsequences ending with a certain value.
- sum: total of sums (value sums) of these subsequences.
We use modulo arithmetic at every step to avoid overflow.