查找数组中的范围

时间:2011-03-02 21:17:17

标签: algorithm language-agnostic

我一直在努力寻找下列(有趣的)问题的最佳解决方案:最终我找到了一个足够好的解决方案,但我想知道是否有更好的解决方案。

1 ... a n 成为一个字符串数组。

设s 1 ... s k 是一个无序的字符串列表,它们都是数组的成员。

任务是在s中找到a封面的最小索引范围元素集。

例如,如果a = [“x”,“y”,“a”,“f”,“c”]和s = {“c”,“y”,“f”},答案是be(1; 1),(3; 4),假设数组从零开始索引。

a通常相当大(数十万个元素),而s相对较小,通常长度<1}。日志(长度(a))。

所以问题是:你能为这个问题找到一个节省时间的算法吗? (在合理范围内,空间效率不是一个问题。)

快速但重要的更新:我需要使用不同的s值执行此操作,但需要使用相同的a。因此,允许基于a的预计算内容,实际上它是唯一的方法。

3 个答案:

答案 0 :(得分:3)

构建哈希表H(a)以在a时间和空间中从元素到索引进行映射:->x x O(n)。然后在H(a)中查找每个 y (平均O(1)时间内O(k)的{​​{1}}总数,并跟踪范围。为此,您可以使用按s排序的pair(min_index, max_index)数组并进行二分搜索,以找到范围或应插入新1元素范围的位置。
总的来说,上面的解决方案需要min_index时间和O( n + k + k * log( nb_ranges ) )空间。

答案 1 :(得分:1)

这就是你想要的,用python编写:

def flattened(indexes):
    s, rest = indexes[0], indexes[1:]
    result = (s, s)
    for e in rest:
        if e == result[1] + 1:
            result = (result[0], e)
        else:
            yield result
            result = (e, e)
    yield result

a = ["x", "y", "a", "f", "c"]
s = ["c", "y", "f"]

# Create lookup table of ai to index in a
src_indexes = dict((key, i) for i, key in enumerate(a))

# Create sorted list of all indexes into a
raw_dst_indexes = sorted(src_indexes[key] for key in s)

# Convert sorted list of indexes into an array of ranges
dst_indexes = [r for r in flattened(raw_dst_indexes)]

print dst_indexes

答案 2 :(得分:0)

我认为你可以把S的元素抛到一个集合或散列表中,任何接近O(1)的东西都要检查成员资格。然后在A上进行线性扫描,用一个标志来确定你当前是否正在覆盖S中的元素,以及该封面的起始位置。应该是O(n + k)。