问题k-subvector使用动态编程

时间:2011-01-26 17:00:46

标签: algorithm dynamic-programming

给定n个整数的向量V和整数k,k <= n,你需要一个最大长度的子向量(一个连续的向量元素序列),最多包含k个不同的元素。

我用于解决问题的技术是动态编程。 该算法的复杂性必须为O(n * k)。

主要问题是如何计算向量的不同元素。你会解决它吗?

如何写出递归公式?

谢谢!!!。

2 个答案:

答案 0 :(得分:2)

我不知道为什么你会坚持使用O(n*k),这可以通过{滑动窗口'方法在O(n)中解决。

  1. 维持当前的“窗口”[left..right]
  2. 在每一步,如果我们可以将right增加1(不违反“最多k个disctint元素”的要求),那么就这样做
  3. 否则,请将left增加1
  4. 检查当前窗口是否最长并返回#2
  5. 检查我们是否可以在#2中增加right有点棘手。我们可以使用哈希表存储窗口内的每个元素在那里发生了多少次。

    因此,允许right增加的条件看起来像

    hash.size < k || hash.contains(V[right + 1])
    

    每次leftright增加时,我们都需要更新哈希值(减少或增加给定元素的出现次数)。

    我很确定,这里的任何DP解决方案都会更长,更复杂。

答案 1 :(得分:0)

  

主要问题是如何计算向量的不同元素。你会解决它吗?

如果您允许使用散列,则可以执行以下操作

init Hashtable h
distinct_count := 0
for each element v of the vector V
    if h does not contain v (O(1) time in average)
        insert v into h (O(1) time in average)
        distinct_count := distinct_count + 1
return distinct_count

这是平均O(n)时间。

如果不是这里是O(n log n)解决方案 - 这次最坏的情况

sort V (O(n log n) comparisons)
Then it should be easy to determine the number of different elements in O(n) time ;-)

我还可以告诉你一个算法在O(n * b)中对V进行排序,其中b是整数的位数 - 如果这对你有帮助的话。

以下是算法:

sort(vector, begin_index, end_index, currentBit)
    reorder the vector[begin_index to end_index] so that the elements that have a 1 at bit currentBit are after those that have a 0 there (O(end_index-begin_index) time)
    Let c be the count of elements that have a 0 at bit currentBit (O(end_index-begin_index) time; can be got from the step before)
    if (currentBit is not 0)
        call sort(vector, begin_index, begin_index+c)
        call sort(vector, begin_index+c+1, end_index)

用它来打电话 vector = V. begin_index = 0 end_index = n-1 currentBit =整数的位数(=:b)-1。

这甚至可以按要求使用动态编程。

正如你可以很容易地确定的那样,这是一个递归深度为b的O(n * b)时间。