问题
给定一组非负整数
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]
范围内
我的代码
public int numRange(ArrayList<Integer> a, int b, int c) {
int curr_sum = a.get(0), start = 0;
int i = 0, count = 0;
for (i = 1; i < a.size(); i++) {
// If curr_sum exceeds the sum, then remove the starting elements
while (curr_sum > c) {
curr_sum = curr_sum - a.get(start);
start++;
}
// If curr_sum becomes equal to sum, then return true
if (b <= curr_sum && curr_sum <= c) {
count++;
}
// Add this element to curr_sum
if (i < a.size())
curr_sum = curr_sum + a.get(i);
}
return count;
}
问题:错误答案。
我遗失的案例是什么? 在纠正之后如何提高此代码的效率?
答案 0 :(得分:2)
public static int numRange(ArrayList<Integer> a, int b, int c) {
int counter =0;
int result =0;
for(int i =0; i< a.size(); i++){
result = a.get(i);
if( result >= b && result <= c){
counter++;
}
int k =i+1;
while(k< a.size()){
result = result+ a.get(k);
if( result >= b && result <= c){
counter++;
}
else if( result >c){
break;
}
k++;
}
}
return counter;
}
答案 1 :(得分:0)
你的方法错过了许多后续步骤。假设输入为[1, 2, 3, 4, 5]
,间隔为(2, 9)
。您的算法会计算[1, 2]
和[1, 2, 3]
。当它到达[1, 2, 3, 4]
时,由于总和太大,您可以从子序列的开头消除数字,直到总和在范围内。但是,这将如何计算[2]
,[2, 3]
或[3]
?此时,您不再计算以4之前的任何内容结束的子序列。
我不知道答案。要使用基本(但可能效率太低)的方法,您需要使用双循环来检查所有子序列。为了提高效率,你需要更加聪明。例如,如果子序列a[i] .. a[j]
的总和大于&lt; = c
,那么所有较小的子序列也会得到总和&lt; = c
,并且您可以使用简单计算子序列的数量代数 - 但是也要确定哪些也有&gt; = b
。