查找通过所有唯一路径的“最短索引范围”的大小

时间:2019-03-29 04:33:11

标签: algorithm kotlin

给出一个String数组,查找“ 最短索引范围”的大小,该大小查找所有唯一路径都通过了。

示例A = { E, R, E, R, A, R, T, A },应为 5 。如我们所见,A[2] = E and A[6] = T的范围包含所有唯一路径。 (在这种情况下,E,R,A,T)

我可以用下面的多重循环来解决。 (由Kotlin解决。)

fun problem(array: Array<String>): Int {
    if (array.isEmpty()) return 0
    val unique = array.distinct()
    var result = 200000
    for (i in 0 until A.size) {
        val tempSet = HashSet<String>()
        val remaining = A.sliceArray(i until array.size)
        var count = 0

        while (true) {
            tempSet.add(remaining[count])
            if (unique.size == tempSet.size) break
            count++

            if (count == remaining.size) {
                count = 200000
                break
            }
        }

        result = Math.min(result, count + 1)
    }

    return result
}

但是,当有大量阵列(大约100,000个)进入时,我不知道如何减少时间。我该怎么办?

一些测试用例:

  1. [E,R,E,R,A,R,T,A]->5。因为[2..6]包含所有唯一路径。 (E,R,A,T)

  2. [C,A,A,R,C,A,A,R]-> 3.因为[3..5]包含所有唯一路径。 (C,A,R)

  3. [R,T,A,R,A,R,E,R]->6。因为[1..6]包含所有唯一路径。 (T,A,R,E)

  4. [A,R,R,C,T,E,A,R]->5。因为[2..6]包含所有唯一路径。 (R,C,T,E,A)

2 个答案:

答案 0 :(得分:2)

使用“两指针”方法可以有效解决此问题。

使字典结构包含char作为键,并将counter作为值(在最简单的情况下-int数组)

将两个索引L和R设置为0。

向右移动R,以获取相应dict元素的当前char增量计数器。 当dict大小(对于数组-非零元素数)等于unique时,停止

现在右移L,对于相应的dict元素的当前char减量计数器,当counter变为零时将其删除。当dict大小小于unique时,请停止。在最后一步,L..R间隔包含所有可能的项目。

继续使用R等等

选择扫描期间的最短间隔。

类似问题here的Python代码

答案 1 :(得分:0)

“所有唯一路径”一词我将解释为“所有可能的值”。

对于具有n唯一值的长度k的字符串,这可以在时间O(n log(k))时使用字典和优先级队列来解决。关键思想是这样:

  1. 在第一遍中,找到所有可能的值。
  2. 第二次,保留字典most_recently_found,其中包含每个值的最新发现。
  3. 保持优先级队列longest_since的值自找到以来最长的时间。
  4. 保持最短间隔的最小运行。

现在,当您回顾并找到所有值时,将遵循每次迭代逻辑,如下所示:

most_recently_found[current_value] = current_position
oldest = longest_since.top()
if current_value == oldest.value:
    while oldest.position() != most_recently_found[oldest.position()]:
        longest_since.pop()
        longest_since.push({value: top.value, position: most_recently_found[oldest.position()]
        oldest = longest_since.top()
if current_position - oldest.position() < best_gap:
    best_gap = current_position - oldest.position()

问题在于,对于找到的每个值,您都必须更新字典(O(1)),可能必须将其从优先级队列(O(k))中删除,可能必须添加一些新内容优先级队列(O(k)),可能需要做一些算术(O(1))。因此,O(n log(k))适用于一切。