lintcode404子数组求和II

描述

给定一个数组和一个范围,求子数组的和在这个范围的所有子数组数。

思路

暴力枚举,O(n^2)超时:

from typing import (
    List,
)

class Solution:
    """
    @param a: An integer array
    @param start: An integer
    @param end: An integer
    @return: the number of possible answer
    """
    def subarray_sum_i_i(self, a: List[int], start: int, end: int) -> int:
	    ans = 0
	    for i in range(len(a)):
		    tmp = 0
		    for j in range(i, len(a)):
			    tmp += a[j]
			    if tmp>end:
				    break
			    if tmp>=start and tmp<=end:
				    ans += 1
	    return ans
				



two pointers,通过。O(n)时间复杂度,O(n)空间复杂度。
首先记录前缀和。
假设数组a为题目给的数组,[start,end]为题目给的范围。
遍历数组a,尝试以当前元素a[i]为起始,向右找,找到第一个元素a[l],使得从a[i]到a[l]的子数组的和等于或大于start。
从数组a的末尾往左找,找到第一个元素a[r],使得从a[i]到a[r]的子数组的和小于或等于end。
如果没找到a[l]或a[r]就退出遍历,因为现在没找到,以后更找不到,这是由前缀和的特性决定的。

from typing import (
    List,
)

class Solution:
    """
    @param a: An integer array
    @param start: An integer
    @param end: An integer
    @return: the number of possible answer
    """
    def subarray_sum_i_i(self, a: List[int], start: int, end: int) -> int:
	    n = len(a)
	    ans = 0
	    if n == 0:
		    return 0
	    pre_sum = [0 for i in range(n+1)]
	    for i in range(1, n+1):
		    pre_sum[i] = pre_sum[i-1] + a[i-1]


	    for i in range(1, n+1):
		    l=i
		    while l<n and pre_sum[l]-pre_sum[i]+a[i-1]<start:
			    l += 1
		    if pre_sum[l]-pre_sum[i]+a[i-1]<start:
			    break
		    r=n
		    while l<r and pre_sum[r]-pre_sum[i]+a[i-1]>end:
			    r -= 1
		    if pre_sum[r]-pre_sum[i]+a[i-1]>end:
			    break


		    ans += r-l+1
		    print(ans)
	    return ans


				



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值