美文网首页
LeetCode---327. Count of Range S

LeetCode---327. Count of Range S

作者: LuDon | 来源:发表于2019-04-19 17:46 被阅读0次

    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
    

    相关文章

      网友评论

          本文标题:LeetCode---327. Count of Range S

          本文链接:https://www.haomeiwen.com/subject/bhscgqtx.html