求和范围内的子数组数
Number of subarrays within a sum range
问题
给定一个非负整数数组 A 和一个范围 (B, C),
找出数组中总和 S 在 [B, C] 或 B <= S <= C
范围内的连续子序列的数量
连续子序列定义为所有数字A[i], A[i + 1], .... A[j]
其中 0 <= i <= j < size(A)
示例:
A : [10, 5, 1, 0, 2]
(B, C) : (6, 8)
ans = 3
[5, 1], [5, 1, 0], [5, 1, 0, 2] 是仅有的 3 个连续子序列,其总和在 [6, 8]
范围内
我的代码
def numRange(A, B, C):
n = len(A)
count = 0
for i in xrange(n-1):
newsum = A[i]
j = i + 1
while newsum <= C and j < n:
if newsum >= B :
count += 1
newsum += A[j]
j += 1
if A[n-1] >= B and A[n-1] <= C:
count += 1
return count
问题:答案错误。
- 我遗漏了哪些案例?
- 这段代码整改后如何提高效率?
服从
def numRange(A, B, C):
n = len(A)
sets = []
for i in range(n):
sum = 0
j = i
while sum < B and j < n:
sum += A[j]
j += 1
while sum >= B and sum <= C and j <= n:
if sum <= C:
sets.append(A[i:j])
if j < n:
sum += A[j]
j += 1
return sets
sets = numRange([10, 5, 1, 0, 2], 6, 8)
print len(sets) # 3
print sets # [[5, 1], [5, 1, 0], [5, 1, 0, 2]]
我使用的策略是有效地缓冲结果,直到我到达终点,然后处理缓冲区的剩余部分。因此,这最多需要两次迭代或 O(n) 时间。
编辑:删除了对 sum()
:
的调用
def numRange(A, B, C):
current = []
current_sum = 0
count = 0
for number in A:
current.append(number)
current_sum += number
while current_sum > C:
current_sum -= current[0]
current = current[1:]
if B <= current_sum <= C:
count += 1
print current_sum, current
# Now check the remaining items in current, in case of a trailing sequence:
# Test with A = [10, 5, 1, 0, 2, 4] to demonstrate the need.
if not current:
return count
current_sum -= current[0]
current = current[1:]
while (B <= current_sum <= C):
count += 1
print current_sum, current
current_sum -= current[0]
current = current[1:]
return count
print "Total of %d subarrays" % numRange( [10, 5, 1, 0, 2], 6, 8)
print
print "Total of %d subarrays" % numRange( [10, 5, 1, 0, 2, 4], 6, 8)
输出:
6 [5, 1]
6 [5, 1, 0]
8 [5, 1, 0, 2]
Total of 3 subarrays
6 [5, 1]
6 [5, 1, 0]
8 [5, 1, 0, 2]
7 [1, 0, 2, 4]
6 [0, 2, 4]
6 [2, 4]
Total of 6 subarrays
您的代码的问题是针对 [5, 1, 0, 2] 的情况。您计算等于 8 的总和。然后将 j 递增到 5
newsum += A[j] # newsum was 6, add A[4] = 2, now 8
j += 1
但随后循环退出,因为 j 现在等于 5,j < n 条件失败。因此,对于这个总和,计数的增量永远不会发生。不幸的是,仅仅改变内循环中事物的顺序不足以修复它。
这是我的 O(n^2) 最坏情况解决方案。额外的 O(1) space。谁能在 O(n)
中给出比这更好的解决方案
class Solution:
def numRange(self, A, B, C):
count = 0
end = len(A)-1
tot = 0
temp_sum = 0
temp_array = []
tot_sum = sum(A[0:len(A)])
for i in range(len(A)):
current_sum = 0
for j in range(i,len(A)):
current_sum += A[j]
if(current_sum > C):
break
elif(B <= current_sum <= C):
#print current_sum
tot += 1
tot_sum -= A[i]
if(tot_sum < B):
break
return tot
问题
给定一个非负整数数组 A 和一个范围 (B, C),
找出数组中总和 S 在 [B, C] 或 B <= S <= C
连续子序列定义为所有数字A[i], A[i + 1], .... A[j] 其中 0 <= i <= j < size(A)
示例:
A : [10, 5, 1, 0, 2]
(B, C) : (6, 8)
ans = 3
[5, 1], [5, 1, 0], [5, 1, 0, 2] 是仅有的 3 个连续子序列,其总和在 [6, 8]
我的代码
def numRange(A, B, C):
n = len(A)
count = 0
for i in xrange(n-1):
newsum = A[i]
j = i + 1
while newsum <= C and j < n:
if newsum >= B :
count += 1
newsum += A[j]
j += 1
if A[n-1] >= B and A[n-1] <= C:
count += 1
return count
问题:答案错误。
- 我遗漏了哪些案例?
- 这段代码整改后如何提高效率?
服从
def numRange(A, B, C):
n = len(A)
sets = []
for i in range(n):
sum = 0
j = i
while sum < B and j < n:
sum += A[j]
j += 1
while sum >= B and sum <= C and j <= n:
if sum <= C:
sets.append(A[i:j])
if j < n:
sum += A[j]
j += 1
return sets
sets = numRange([10, 5, 1, 0, 2], 6, 8)
print len(sets) # 3
print sets # [[5, 1], [5, 1, 0], [5, 1, 0, 2]]
我使用的策略是有效地缓冲结果,直到我到达终点,然后处理缓冲区的剩余部分。因此,这最多需要两次迭代或 O(n) 时间。
编辑:删除了对 sum()
:
def numRange(A, B, C):
current = []
current_sum = 0
count = 0
for number in A:
current.append(number)
current_sum += number
while current_sum > C:
current_sum -= current[0]
current = current[1:]
if B <= current_sum <= C:
count += 1
print current_sum, current
# Now check the remaining items in current, in case of a trailing sequence:
# Test with A = [10, 5, 1, 0, 2, 4] to demonstrate the need.
if not current:
return count
current_sum -= current[0]
current = current[1:]
while (B <= current_sum <= C):
count += 1
print current_sum, current
current_sum -= current[0]
current = current[1:]
return count
print "Total of %d subarrays" % numRange( [10, 5, 1, 0, 2], 6, 8)
print
print "Total of %d subarrays" % numRange( [10, 5, 1, 0, 2, 4], 6, 8)
输出:
6 [5, 1]
6 [5, 1, 0]
8 [5, 1, 0, 2]
Total of 3 subarrays
6 [5, 1]
6 [5, 1, 0]
8 [5, 1, 0, 2]
7 [1, 0, 2, 4]
6 [0, 2, 4]
6 [2, 4]
Total of 6 subarrays
您的代码的问题是针对 [5, 1, 0, 2] 的情况。您计算等于 8 的总和。然后将 j 递增到 5
newsum += A[j] # newsum was 6, add A[4] = 2, now 8
j += 1
但随后循环退出,因为 j 现在等于 5,j < n 条件失败。因此,对于这个总和,计数的增量永远不会发生。不幸的是,仅仅改变内循环中事物的顺序不足以修复它。
这是我的 O(n^2) 最坏情况解决方案。额外的 O(1) space。谁能在 O(n)
中给出比这更好的解决方案class Solution:
def numRange(self, A, B, C):
count = 0
end = len(A)-1
tot = 0
temp_sum = 0
temp_array = []
tot_sum = sum(A[0:len(A)])
for i in range(len(A)):
current_sum = 0
for j in range(i,len(A)):
current_sum += A[j]
if(current_sum > C):
break
elif(B <= current_sum <= C):
#print current_sum
tot += 1
tot_sum -= A[i]
if(tot_sum < B):
break
return tot