计算存储在数组中的所有相邻节点列表

时间:2010-04-01 13:06:51

标签: java algorithm arrays function

这个问题有许多天真的方法,但我正在寻找一个好的解决方案。这是问题(将在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 ]是一个“坏”阵列。

我们想要所有“好”数组的长度计数,而不是“好”数组的子数组。此外,如上所述,“好”数组可能从另一个“好”数组的中间开始,但两者的组合可能是“坏”数组。

2 个答案:

答案 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的子数组的属性是“好”,那么任何较小的子阵列也都很好。

算法如下:

  • 从包含第一个元素(或对,或任何最短单位)的子数组开始。
  • 3月向下的子阵列(即推进子阵列的开始和结束),直到你得到“好”的答案。
  • 推进子阵列的结束直到得到“坏”的答案。在您遇到“坏”之前的子阵列是该位置上最长的好子阵列 - 计算它(或保存它,或者您想用它做什么)。
  • 现在推进子阵列的开始直到你得到“好”的答案;如果你赶上子阵列的末尾,向前滑动。然后重复上一步。
  • 当你的子阵列结束时,你的完整阵列结束了,你已经完成了。