LeetCode---327. Count of Range Sum

Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.
Range sum S(i, j) is defined as the sum of the elements in nums between indices i and j (i ≤ j), inclusive.

Note:
A naive algorithm of O(n2) is trivial. You MUST do better than that.

Example:

Input: nums = [-2,5,-1], lower = -2, upper = 2,
Output: 3 
Explanation: The three ranges are : [0,0], [2,2], [0,2] and their respective sums are: -2, -1, 2.

解題思路:
1、累加nums元素置為sums列表中;
2、對于nums中的每個元素,需要找到其前面元素之差在范圍內(nèi),即lower <= sums[i] - sums[j] <= upper, 即對于每個元素sums[i], 需要找sums[i] - upper <= sums[j] <= sums[i] -lower范圍內(nèi)的個數(shù),既可以通過尋找左右邊界的索引來求得范圍內(nèi)元素的個數(shù)。
3、另外,如果元素sums[i]本身在范圍內(nèi)的話,需要在sums中加入元素0。
solution:

class Solution(object):
    def countRangeSum(self, nums, lower, upper):
        """
        :type nums: List[int]
        :type lower: int
        :type upper: int
        :rtype: int
        """
        import bisect
        # 求前n項和nums,
        # 如果 lower <= nums[j] - nums[i] <= upper, j > i 則滿足要求
        # nums[j] -upper <= nums[i] <= nums[j] - lower, 即在nums中,小于j的索引中找上下界索引的位置,位置之差為滿足條件的個數(shù)
        # 由于nums[i] 可以為0, 即nums[j]就滿足要求,因為nums中需要加入初始元素0
        # 
        res = 0
        sums = [0]
        sum1 = 0
        for i in range(len(nums)):
            sum1 += nums[i]
            left_bound = sum1 - upper
            right_bound = sum1 - lower
            # left = bisect.bisect_left(sums, left_bound)
            # right = bisect.bisect_right(sums, right_bound)
            left = self.left_bound(sums, left_bound)
            right = self.right_bound(sums, right_bound)
            res += right - left
            sums.append(sum1)
            sums.sort()
        return res
    def left_bound(self, nums, target):
        left, right = 0, len(nums)
        while(left < right):
            mid = left + (right-left)/2
            if nums[mid] < target:
                left = mid+1
            else:
                right = mid
        return left
    def right_bound(self, nums, target):
        left, right = 0, len(nums)
        while(left < right):
            mid = left + (right-left)/2
            if nums[mid] <= target:
                left = mid+1
            else:
                right = mid
        return right
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容