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
left
toright
indices (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 isn
is 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
→ Add1
tosubarraySums
j = 1
:currentSum = 1 + 2 = 3
→ Add3
tosubarraySums
j = 2
:currentSum = 1 + 2 + 3 = 6
→ Add6
tosubarraySums
j = 3
:currentSum = 1 + 2 + 3 + 4 = 10
→ Add10
tosubarraySums
- For
i = 1
, generate subarrays starting from index1
:j = 1
:currentSum = 2
→ Add2
tosubarraySums
j = 2
:currentSum = 2 + 3 = 5
→ Add5
tosubarraySums
j = 3
:currentSum = 2 + 3 + 4 = 9
→ Add9
tosubarraySums
- For
i = 2
, generate subarrays starting from index2
:j = 2
:currentSum = 3
→ Add3
tosubarraySums
j = 3
:currentSum = 3 + 4 = 7
→ Add7
tosubarraySums
- For
i = 3
, generate subarrays starting from index3
:j = 3
:currentSum = 4
→ Add4
tosubarraySums
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 betweenleft
andright
, 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 betweenleft
andright
, 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 betweenleft
andright
, 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 betweenleft
andright
, 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 betweenleft
andright
, 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
|
|