我写了一个代码,找到数组中最长的连续体,连续体中的值之和等于零模3,例如对于数组a[]={2,-3,5,7,-20,7}
我们有2-3 + 5 + 7-20 = -9因此输出为5,我的问题复杂性,现在是O(n^3)
一只小鸟低声说我可以在O(n)
public class mmn {
public static void main(String[] args)
{
int a[]={2,-3,5,7,-20,7};
int r=what(a);
System.out.println(r);
}
private static int f(int[]a,int low, int high)
{
int res=0;
for (int i=low;i<=high;i++)
res+=a[i];
return res;
}
public static int what(int[]a)
{
int temp=0;
for(int i=0;i<a.length;i++)
{
for (int j=i;j<a.length;j++)
{
int c=f(a,i,j);
if (c%3==0)
{
if(j-i+1>temp)
temp=j-i+1;
}
}
}
return temp;
}
}
尝试在O(n)中重写:
import java.util.*;
class Main {
public static void main (String[] args) throws Exception {
// you should use only one Scanner object
Scanner scanner = new Scanner(System.in);
int a[]={3,1,3,1,3,1};
int n=a.length;
int S[]=new int[n];
int i[]=new int[n];
int best;
int sum;
for (int j=0; j<n; j++) {
S[j]=a[j]%3;
i[j]=j;// initialize
//System.out.println(S[j]);
//System.out.println(i[j]);
}
best=1;
for (int k=1; k<n; k++) {
if((S[k-1]+S[k])%3==0) {//checking if we want a longer continuum
S[k]=S[k-1]+a[k];
i[k]=i[k-1];
}
if(S[k]<S[best])//check if i should update the better
best=k-1;
}
System.out.println(best);
}
}
答案 0 :(得分:2)
在使用动态编程计算前缀sum s []之后,您可以迭代s并存储在索引i中的对s [i]%3的新数组中,使得第一个索引是最小索引,第二个索引是最小索引是最大的indeces,所以新数组的长度为3,然后迭代新数组并存储0,1,2的计数,最后再次迭代该数组,并找到最大值 (cnt [3 - moduloArray [i]] .first - i,cnt [3 - moduloArray [i]] .second - i)。
答案 1 :(得分:1)
以下是Python中O(n)
算法的示例,对数组进行了一次传递。我们的想法是dp[i][r]
代表最长的序列s
,以i
的{{1}}结尾。 Cleary我们寻找最高(sum s) % 3 = r
。如果前一步骤为适当的模数结果记录了任何长度,我们只能增加特定单元格的序列。由于我们在每次迭代通过数组时只访问三个单元格(常量),因此该算法具有dp[i][0]
时间和空间复杂度。 (空间可以很容易地适应O(n)
,因为我们在每次迭代时只需要前三个单元格。)
O(1)
答案 2 :(得分:-1)
为了它的乐趣:
List<List<Integer>> list = IntStream.range(0, arrayLenght).mapToObj(x -> x)
.flatMap(i -> IntStream.range(i, arrayLenght)
.mapToObj(j -> Arrays.stream(array).skip(i).limit(arrayLenght - j).mapToObj(t -> t)
.collect(Collectors.toList())))
.collect(Collectors.toList());
int result = list.stream().filter(l -> l.stream().collect(Collectors.summingInt(u -> u)) % 3 == 0)
.max(Comparator.comparing(List::size))
.map(List::size)
.orElse(-1);
使用少量操作可能会进一步改进。
但至少它适用于以下输入:
[1,3,3,3,1]