问题描述
我看到以下问题并试图找到答案。
Question: Given a sequence of positive integers A and an integer T, return whether there is a *continuous sequence* of A that sums up to exactly T
Example
[23, 5, 4, 7, 2, 11], 20. Return True because 7 + 2 + 11 = 20
[1, 3, 5, 23, 2], 8. Return True because 3 + 5 = 8
[1, 3, 5, 23, 2], 7 Return False because no sequence in this array adds up to 7
Note: We are looking for an O(N) solution. There is an obvious O(N^2) solution which is a good starting point but is not the final solution we are looking for.
我对上述问题的回答是:
public class Tester {
public static void main(String[] args) {
int[] myArray = {23, 5, 4, 7, 2, 11};
System.out.println(isValid(myArray, 20));
}
public static boolean isValid(int[] array, int sum) {
int pointer = 0;
int temp = 0;
while (pointer < array.length)
{
for (int i = pointer; i < array.length; i++)
{
if (array[i] > sum)
break;
temp += array[i];
if (temp == sum)
return true;
else if (temp > sum)
break;
// otherwise continue
}
temp = 0;
pointer++;
}
return false;
}
}
我认为我的答案是 O(N^2),根据问题,这是不可接受的。 是否有基于 O(N) 的解决方案?
1楼
您实际上只需要循环一次,即 O(N)。
从索引 0 开始添加,一旦超过sum
就从数组的开头开始删除。
如果temp
低于sum
继续循环。
public static boolean isValid(int[] array, int sum) {
int init = 0,temp = 0;
for (int i = 0; i < array.length; i++) {
temp += array[i];
while (temp > sum) {
temp -= array[init];
init++;
}
if (temp == sum)
return true;
}
return false;
}
2楼
您应该做的是有两个索引(开始和停止),然后增加stop
直到总和达到要求(并返回true
)或更高。
然后你增加start
直到总和是所需的(并返回true
或以下。然后你重复这个直到你到达数组的末尾。你可以增量更新总和(当你增加stop
时添加元素,当你增加start
时减去元素) ). 这应该是 O(N)。
下面是一个例子:
public class t {
public static void main(String[] args) {
int[] myArray = {23, 5, 4, 7, 2, 11};
System.out.println(isValid(myArray, 20));
}
public static boolean isValid(int[] array, int sum) {
int start = 0;
int stop = 0;
int tsum = 0;
while( true )
{
if( tsum < sum )
{
if( stop >= array.length )
break;
tsum += array[stop];
stop++;
}
else if( tsum > sum )
{
tsum -= array[start];
start++;
}
else if( tsum == sum )
return true;
// System.out.println(start + " -- " + stop + " => " + tsum);
}
return false;
}
}