Problem
You are given the array nums consisting of n positive integers. You computed the sum of all non-empty continuous subarrays from the array and then sorted them in non-decreasing order, creating a new array of n * (n + 1) / 2 numbers.
Return the sum of the numbers from index left to index right (indexed from 1), inclusive, in the new array. Since the answer can be a huge number return it modulo 10^9 + 7.
Examples
Example 1:
| |
Example 2:
| |
Example 3:
| |
Solution
Video Explanation
Please refer to the video below:
Method 1 - Naive Approach
To solve this problem, we’ll first need to compute the sum of all non-empty continuous subarrays, then sort the resulting sums, and finally determine the sum of a specified range of these sorted subarrays. Given the potential size of the array and the need for efficiency, here’s a step-by-step approach:
Approach:
- Compute All Subarray Sums:
- Compute the sum of all non-empty continuous subarrays from the input array.
- Store these sums in a list.
- Sort the Subarray Sums:
- Sort the list of subarray sums in non-decreasing order.
- Compute the Sum of a Specific Range:
- Sum the elements in the list from the
lefttorightindices (inclusive).
- Sum the elements in the list from the
- Modulo Operation:
- Since the result can be very large, take the sum modulo (10^9 + 7).
Code
| |
| |
Complexity
- ⏰ Time complexity:
O(n^2 log n)where isnis length of input array- Generating subarray takes
O(n^2) - Sorting takes O(m log m) where m =
n*(n+1)/2 - Summing takes O(right - left), in worst case O(n)
- Generating subarray takes
- 🧺 Space complexity:
O(n^2)
Dry Run
Compute all subarrays
Loop through starting index i and ending index j to compute all possible subarray sums.
- For
i = 0, generate subarrays starting from index0:j = 0:currentSum = 1→ Add1tosubarraySumsj = 1:currentSum = 1 + 2 = 3→ Add3tosubarraySumsj = 2:currentSum = 1 + 2 + 3 = 6→ Add6tosubarraySumsj = 3:currentSum = 1 + 2 + 3 + 4 = 10→ Add10tosubarraySums
- For
i = 1, generate subarrays starting from index1:j = 1:currentSum = 2→ Add2tosubarraySumsj = 2:currentSum = 2 + 3 = 5→ Add5tosubarraySumsj = 3:currentSum = 2 + 3 + 4 = 9→ Add9tosubarraySums
- For
i = 2, generate subarrays starting from index2:j = 2:currentSum = 3→ Add3tosubarraySumsj = 3:currentSum = 3 + 4 = 7→ Add7tosubarraySums
- For
i = 3, generate subarrays starting from index3:j = 3:currentSum = 4→ Add4tosubarraySums
subarraySums becomes:
| |
Sort the subarraySums
| |
Compute the sum between the range
Sum the elements from index left - 1 = 0 to right - 1 = 4 inclusive.
| |
Method 2 - Using Heap with Sum and Index pair
We can add pair to priority queue, with sum and index. Where sum = nums[i] + ... + nums[j], and index = j + 1. The reason for this is, lets look at subarraySums, corresponding to index + 1:
| |
So, we can pop out pair from minHeap and add it back if index + 1 < n. This is similar to Generate Kth Ugly Number.
Here are the steps we can take:
Code
| |
| |
Complexity
- ⏰ Time complexity:
O(right * log n) - 🧺 Space complexity:
O(n)
Dry Run
Initial Pairs
Insert initial pairs into the priority queue: [ (1,1), (2,2), (3,3), (4,4) ]
Processing
Iteration 1
- Pop the smallest sum:
(1,1) - Since
i= 1 is betweenleftandright, add(1,1)sum toans.ans = (0 + 1) % MOD = 1
- Push next sum:
(1+2, 2) = (3,2) - Queue now:
[ (2,2), (3,2), (3,3), (4,4) ]
Iteration 2
- Pop the smallest sum:
(2,2) - Since
i= 2 is betweenleftandright, add(2,2)sum toans.ans = (1 + 2) % MOD = 3
- Push next sum:
(2+3, 3) = (5,3) - Queue now:
[ (3, 2), (4, 4), (3, 3), (5, 3) ]
Iteration 3
- Pop the smallest sum:
(3, 2) - Since
i= 3 is betweenleftandright, add(3, 2)sum toans.ans = (3 + 3) % MOD = 6
- Push next sum:
(3 + 3 = 6, 3) - Queue now:
[(3, 3), (4, 4), (5, 3), (6, 3)]
Iteration 4
- Pop the smallest sum:
(3, 3) - Since
i= 4 is betweenleftandright, add(3, 3)sum toans.ans = (6 + 3) % MOD = 9
- Push next sum:
(3 + 4 = 7, 4) - Queue now:
[(4, 4), (6, 3), (5, 3), (7, 4)]
Iteration 5
- Pop the smallest sum:
(4, 4) - Since
i= 5 is betweenleftandright, add(4, 4)sum toans.ans = (9 + 4) % MOD = 13
- Queue now:
[(5, 3), (6, 3), (7, 4)](Nothing to push as index of Node(4) has reached n=4)
Final Results
| |