返回数组中重复数字序列的索引

时间:2012-06-12 22:34:01

标签: algorithm

给出一个数组:

array = [16 16 16 22 23 23 23 25 52 52 52]

我想返回一个指向三个重复数字元素的索引列表。 在这种情况下,将是:

indices = find_sequence(nbr_repeats = 3)
print indices
 [0 1 2  4 5 6  8 9 10] 

用于实现find_sequence的最快和最优雅的算法是什么?

4 个答案:

答案 0 :(得分:2)

我知道的最简单的方式......记下你看到一个数字的第一个地方。继续前进直到找到不同的数字,然后如果序列足够长,则从序列的开头直到结束之前添加所有数字。

(当然,在你完成元素检查之后,你还必须检查序列长度。我是通过迭代一遍结束而只是跳过最后一次迭代的元素检查来完成的。)

To find_repeats (input : list, minimum : integer):
    start := 0
    result := []
    for each x from 0 to (input length):
        ' "*or*" here is a short-circuit or
        ' so we don't go checking an element that doesn't exist
        if x == (input length) *or* array[x] != array[start]:
            if (x - start) >= minimum:
                append [start...(x - 1)] to result
            start := x
    return result

答案 1 :(得分:1)

基于OP的假设:

  1. 列表已排序
  2. 最大频率为nbr_repeats
  3. 这可能有效:

    def find_sequence(nbr_repeats, l):
        res = []
        current = -1
        count = 0
        idx = 0
        for i in l:
            if i == current:
                count += 1
                if count == nbr_repeats:
                    for k in reversed(range(nbr_repeats)):
                        res.append(idx-k)
            else:
                current = i
                count = 1
            idx += 1
        return res
    

答案 2 :(得分:1)

这在我看来就像Boyer-Moore string search algorithm的一个特例,并且由于您使用的任何语言都包含字符串搜索的优化,也许最优雅的答案是将您的数据视为字符数组(即字符串) )并使用您的语言内置的字符串搜索功能...请注意,这只适用于您的数字符合您的语言支持的字符集(例如,ASCII中没有大于128的数字)

答案 3 :(得分:0)

由于您未指定语言,因此这是伪代码:

find_sequence(array: array of int, nbr_repeats: int) : array of int
  retVal = emty array of int // the return'd array
  last = empty array of int  // collection of last seen same elements
  i = -1
  for each element e in array
    ++i
    if (isempty(last))
      add(last, e)   // just starting
    else if (count(last, e) >= nbr_repeats)
      add(retVal, i-nbr_repeats) // found an index
    else if (e == first(last))
      add(last, e)   // we have encountered this element before
    else
      if (count(last, e) >= nbr_repeats)
        for (j=nbr_repeats-1; j>0; --j)
          add(retVal, i-j) // catching up to i with indices
      last = [e]     // new element

    if (count(last, e) >= nbr_repeats)
      for (j=nbr_repeats-1; j>0; --j)
        add(retVal, i-j) // handle end of array properly

  return retVal

编辑:删除了关于排序的评论,因为它会破坏原始索引。

注意:您也可以保留最后一个元素及其看到计数,而不是维护最后一个相同元素的列表