使用动态规划解决k-子向量问题

发布于 2024-10-14 20:14:40 字数 194 浏览 5 评论 0原文

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

我用来解决问题的技术是动态规划。 该算法的复杂度必须是O(n*k)。

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

递归方程怎么写?

感谢您!!!。

Given a vector V of n integers and an integer k, k <= n, you want a subvector (a sequence of consecutive elements of the vector ) of maximum length containing at most k distinct elements.

The technique that I use for the resolution of the problem is dynamic programming.
The complexity of this algorithm must be O(n*k).

The main problem is how to count distinct elements of the vector. as you would resolve it ?

How to write the EQUATION OF RECURRENCE ?

Thanks you!!!.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

聆听风音 2024-10-21 20:14:40

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

  1. 维护当前的“窗口”[left..right]
  2. 在每一步中,如果我们可以将 right 加 1(不违反“最多 k 个离散元素”要求),则执行否则
  3. ,将 left 增加 1
  4. 检查当前窗口是否是最长的,然后返回#2

检查是否可以在 #2 中增加 right 有点棘手。我们可以使用哈希表来存储窗口内每个元素出现的次数。

因此,允许 right 增加的条件如下所示

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

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

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

I don't know why you would insist on O(n*k), this can be solved in O(n) with 'sliding window' approach.

  1. Maintain current 'window' [left..right]
  2. At each step, if we can increase right by 1 (without violating 'at most k disctint elements' requirement), do it
  3. Otherwise, increase left by 1
  4. Check whether current window is the longest and go back to #2

Checking whether we can increase right in #2 is a little tricky. We can use hashtable storing for each element inside window how many times it occurred there.

So, the condition to allow right increase would look like

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

And each time left or right is increased, we'll need to update hash (decrease or increase number of occurrences of the given element).

I'm pretty sure, any DP solution here would be longer and more complicated.

红玫瑰 2024-10-21 20:14:40

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

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

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)

调用它
向量=V
开始索引 = 0
结束索引 = n-1
currentBit = 整数的位数 (=: b)​​-1。

这甚至根据要求使用动态编程。

您可以很容易地确定,这是 O(n*b) 时间,递归深度为 b。

the main problem is how to count distinct elements of the vector. as you would resolve it?

If you allowed to use hashing, you could do the following

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

This is in average O(n) time.

If not here is an O(n log n) solution - this time worst case

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

I could also tell you an algorithm to sort V in O(n*b) where b is the bit count of the integers - if this helps you.

Here is the algorithm:

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)

Call it with
vector = V
begin_index = 0
end_index = n-1
currentBit = bit count of the integers (=: b)-1.

This even uses dynamic programming as requested.

As you can determine very easily this is O(n*b) time with a recursion depth of b.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文