Skip to content
LC-1508 Medium LeetCode

1508. Range Sum of Sorted Subarray Sums

Read the full problem statement on LeetCode.
Difficulty: medium Acceptance: 63% Topics: Array, Two Pointers, Binary Search, Sorting, Prefix Sum
View full problem on LeetCode
Reference solution (spoiler · python)
# Time:  O(nlog(sum(nums)))
# Space: O(n)

# binary search + sliding window solution
class Solution(object):
    def rangeSum(self, nums, n, left, right):
        """
        :type nums: List[int]
        :type n: int
        :type left: int
        :type right: int
        :rtype: int
        """
        def countUntil(nums, target):
            result, curr, left = 0, 0, 0
            for right in xrange(len(nums)):
                curr += nums[right]
                while curr > target:
                    curr -= nums[left]
                    left += 1
                result += right-left+1
            return result
        
        def sumUntil(nums, prefix, target):
            result, curr, total, left = 0, 0, 0, 0
            for right in xrange(len(nums)):
                curr += nums[right]
                total += nums[right]*(right-left+1)
                while curr > target:
                    curr -= nums[left]
                    total -= prefix[right+1]-prefix[(left-1)+1]
                    left += 1
                result += total
            return result
            
        def sumLessOrEqualTo(prefix, nums, left, right, count):
            while left <= right:
                mid = left + (right-left)//2
                if countUntil(nums, mid)-count >= 0:
                    right = mid-1
                else:
                    left = mid+1
            return sumUntil(nums, prefix, left)-left*(countUntil(nums, left)-count)
    
        MOD = 10**9+7
        prefix = [0]*(len(nums)+1)
        for i in xrange(len(nums)):
            prefix[i+1] = prefix[i]+nums[i]
        m, M = min(nums), sum(nums)
        return (sumLessOrEqualTo(prefix, nums, m, M, right) -
                sumLessOrEqualTo(prefix, nums, m, M, left-1))%MOD
    

    
# Time:  O(rlogr), worst: O(n^2 * logn)
# Space: O(n)
import heapq


# heap solution
class Solution2(object):
    def rangeSum(self, nums, n, left, right):
        """
        :type nums: List[int]
        :type n: int
        :type left: int
        :type right: int
        :rtype: int
        """
        MOD = 10**9+7
        min_heap = []
        for i, num in enumerate(nums, 1):
            heapq.heappush(min_heap, (num, i))
        result = 0
        for i in xrange(1, right+1):
            total, j = heapq.heappop(min_heap)
            if i >= left:
                result = (result+total)%MOD
            if j+1 <= n:
                heapq.heappush(min_heap, (total+nums[j], j+1))
        return result

Solution from kamyu104/LeetCode-Solutions · MIT