运行要求
运行时间限制: 2sec
内存限制: 1024MB
原题链接
D - Enough Array
题目
有一个长为N的整数数组A= a1,a2,a3,...,an和整数K。数组A中满足以下条件的连续的区间有几个。
- 连续区间的和要大于等于K *
对于两个区间就算元素值是一样的,如果元素的所属位置不一样的话,这样区间按照两个不同区间去对待。
输出的值可能不能通过32bit装下。
要求
- 1 <= ai <= 100000
- 1 <= N <= 1000000
- 1 <= K <= 10000
输入
输入都以以下标准从命令行输入
N K
a1 a2 a3 ... aN
输出
输出满足条件的连续区间的数量
例1
输入
4 10
6 1 2 7
输出
2
- A[1..4] a1,a2,a3,a4(连续区间的和为16)
- A[2..4] a2,a3,a4(连续区间的和为10)
满足条件的连续区间的数量为2
例2
输入
3 5
3 3 3
输出
3
对于两个区间就算元素值是一样的,但是元素的所属位置不一样,这样区间按照两个不同区间去对待。
例3
输入
10 53462
103 35322 232 342 21099 90000 18843 9010 35221 19352
输出
36
解题思路
读懂题目
1. 简单来说就是在一个数组里,找到连续的区间,并且连续的区间的和要小于给定值
思路
1. 找区间就意味着在数组内找两个点
2. 直觉可以告诉我,找到大于等于K的区间的话,要遍历到最后,而反过来找小于K的区间的话,只要遍历一部分(这个看完后就明白了)
3. 长度为N的数组,取出所有两个点的组合有n(n-1)/2种情况这里N=4为例,总共有(4(4-1)) /2 = 6种情况
4.最后的结果就是 第3步减去第2步的值,也就是所有取出两个元素的情况数 - 总和小于K的区间数
5.方法
1. 遍历每个元素,以遍历到的元素为开头,寻找后面的的值,直到区间的值大于等于K
这样的话就是循环里面套循环了,对于N最大值为10的5次方来说,这样的循环里面套循环的话复杂度为O(N2)时间上是不允许的,我第一次提交直接TLE了。
2. 尺取法(日文),Two Pointer Algorithm 这样的话复杂度只有O(N),时间上是允许的。
那么我们以例1为例子
代码
S = input().split(" ")
n = int(S[0])
k = int(S[1])
S = input().split()
arr = [int(s) for s in S]
def calculate(n,k,arr):
j = 0
s = 0
ans = 0
for i in range(n):
while (j < n) and (s + arr[j] < k):
s = s + arr[j]
j = j + 1
ans = ans + j - i
s = s - arr[i]
print(n + (n * (n-1))//2 - ans)
calculate(n,k,arr)
总结
这道题可以作为Two Pointer Algorithm的练习题。
在左区间边界做传统for循环遍历的时候,对右区间边界范围进行Two Pointer Algorithm的计算可以将时间大大缩小。复杂度从O(N2)降为O(N)
另外,在二分法也可适用,目前还没有尝试。
※ 另外,我会在我的微信个人订阅号上推出一些文章,欢迎关注
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。