这个问题有许多天真的方法,但我正在寻找一个好的解决方案。这是问题(将在Java中实现):
你有一个函数foo(int a,int b),如果'a'与'b'“相邻”则返回true,如果'a'不与'b'相邻则返回false。你有一个像[1,4,5,9,3,2,6,15,89,11,24]这样的数组,但实际上有一个很长的长度,比如120,会一遍又一遍地重复(它的遗传算法适应度函数)这就是效率很重要的原因。
我想要一个函数,它返回数组中每个可能的“列表”邻接的长度,但不包括“列表”,它只是更大列表的子集。
例如,如果foo(1,4) - > true,foo(4,5) - > true,foo(5,9) - > false,foo(9,3)& foo(3,2)& foo(2,6),foo(6,15) - >是的,然后有'列表'(1,4,5)和(9,3,2,6),所以长度为3和4.我不希望它返回(3,2,6),但是,因为这只是9,3,2,6的一个子集。
感谢。
修改
抱歉,我刚刚意识到我没有解释整个问题,剩下的部分就是那么困难。让我们重启。忘了第一篇文章。那会让我们感到困惑。
假设有一个函数foo(int [] array),如果数组是“好”数组则返回true,如果数组是“坏”数组则返回false。这里的好坏并不重要。
给定完整的数组[1,6,8,9,5,11,45,16,9],让我们说子阵列[1,6,8]是一个“好”数组和[9,5, 11,45]是一个“好”阵列。此外,[5,11,45,16,9]是一个“好”阵列,也是最长的“好”子阵列。请注意,虽然[9,5,11,45]是一个“好”数组,而[5,11,45,16,9]是一个“好”数组,[9,5,11,45,16,9 ]是一个“坏”阵列。
我们想要所有“好”数组的长度计数,而不是“好”数组的子数组。此外,如上所述,“好”数组可能从另一个“好”数组的中间开始,但两者的组合可能是“坏”数组。
答案 0 :(得分:2)
我认为这个O(n)
算法可以满足您的需求。我怀疑你能够更快地做到这一点,因为你必须分析每个元素。
count = 1;
for each index i from 1 to N
if ( foo(array[i-1], array[i]) == true )
++count;
else
print count;
count = 1;
这是有效的,因为如果某个数字打破了邻接链,那么打破链的数字之前的数字都不能成为更长链的一部分,所以你也可以继续从那一点开始。
在您的示例上执行此操作:
例如,如果foo(1,4) - > true,foo(4,5) - > true,foo(5,9) - > false,foo(9,3)& foo(3,2)& foo(2,6),foo(6,15) - >是的,然后有'列表'(1,4,5)和(9,3,2,6),所以长度为3和4.我不希望它返回(3,2,6),但是,因为这只是9,3,2,6
的一个子集
foo(1,4) - >是的 - > count = 2
foo(1,5) - >是的 - > count = 3
foo(5,9) - > false - > print 3
,count = 1
foo(9,3) - >是的 - > count = 2
foo(3,2) - >是的 - > count = 3
foo(2,6) - >是的 - > count = 4
foo(6,15) - >是的 - > count = 5
数组的结尾,只是打印计数,所以print 5
。我猜你的例子是错的,因为(9, 3, 2, 6)
是(9, 3, 2, 6, 15)
的一个子集......
答案 1 :(得分:0)
我认为,这是在最长子字符串样式问题的类中,可以在单个传递中解决(在O(n)
中),只要您具有从A到B的子数组的属性是“好”,那么任何较小的子阵列也都很好。
算法如下: