LeetCode---327. Count of Range S

2019-04-19  本文已影响0人  LuDon

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中的每个元素,需要找到其前面元素之差在范围内,即lower <= sums[i] - sums[j] <= upper, 即对于每个元素sums[i], 需要找sums[i] - upper <= sums[j] <= sums[i] -lower范围内的个数,既可以通过寻找左右边界的索引来求得范围内元素的个数。
3、另外,如果元素sums[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的索引中找上下界索引的位置,位置之差为满足条件的个数
        # 由于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
上一篇 下一篇

猜你喜欢

热点阅读