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),即, 即對于每個元素sums[i], 需要找
范圍內(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