给定n个整数的向量V和整数k,k <= n,你需要一个最大长度的子向量(一个连续的向量元素序列),最多包含k个不同的元素。
我用于解决问题的技术是动态编程。 该算法的复杂性必须为O(n * k)。
主要问题是如何计算向量的不同元素。你会解决它吗?
如何写出递归公式?
谢谢!!!。
答案 0 :(得分:2)
我不知道为什么你会坚持使用O(n*k)
,这可以通过{滑动窗口'方法在O(n)
中解决。
[left..right]
right
增加1(不违反“最多k个disctint元素”的要求),那么就这样做left
增加1 检查我们是否可以在#2中增加right
有点棘手。我们可以使用哈希表存储窗口内的每个元素在那里发生了多少次。
因此,允许right
增加的条件看起来像
hash.size < k || hash.contains(V[right + 1])
每次left
或right
增加时,我们都需要更新哈希值(减少或增加给定元素的出现次数)。
我很确定,这里的任何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)时间。