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中的每个元素,需要找到其前面元素之差在范围内,即, 即对于每个元素sums[i], 需要找范围内的个数,既可以通过寻找左右边界的索引来求得范围内元素的个数。
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
网友评论