动态编程算法删除数组中的k个元素

时间:2014-08-16 05:59:29

标签: algorithm dynamic-programming

我最近试图解决一个问题,它将n个整数作为输入,我们不得不从数组中删除k个整数,以最大化两个连续项之间的最小差异。

示例测试用例: 阵列:6,7,10,13,15 删除2个整数。

答案:已删除整数:7,13

我的方法:

由于我们必须删除k个整数,所以我们遍历数组k次。在每次迭代中,我们将两个连续项之间的最小差异归为大。 让我们说在一次迭代之后,i和i + 1对具有最小差异。然后我们比较i-1和i + 1之间的差异以及i和i + 2之间的差异。 如果第一个更大,那么我们删除术语i,否则我们删除i + 1.

这种方法给了我一个错误的答案。

由于对n和k的约束较低(1 <= k <= n <= 30)。 我相信问题可以通过动态编程来解决,但我不知道如何处理它。

任何帮助都会很好。我不希望代码只是算法以及它是如何派生的。 提前致谢

2 个答案:

答案 0 :(得分:1)

这是一个相当简单的立方时间算法。如果我们事先决定最小差异,那么线性时间贪婪算法会告诉我们需要删除多少个元素(从左到右扫描一次,只有在过去选择时才需要删除)。迭代所有n选择2 = O(n ^ 2)可能的最小差异并取最大值导致最多k个删除。 (要获得O(n ^ 2 log n):对这些可能的最小值进行排序并使用二进制搜索。)

答案 1 :(得分:0)

这是一个动态编程解决方案。也许存在一个更简单的解决方案,但是这个解决方案是正确的,对于给定的约束来说肯定足够快:

1)假设f(prefix_len, last_taken, deletes_count)是处理数组中prefix_len个数后的两个连续数字之间的最大差异,正好删除deletes_count个数字并且具有索引{{1到目前为止,作为最后剩下的元素。

2)last_index可以使用以下公式计算:
f f(i, i, deletes_count) = max(min(f(i - 1, j, deletes_count), abs(array[i] - array[j])))。 该公式对应于未删除0 <= j < i - 元素的情况 i。该公式对应于删除f(i, j, deletes_count) = f(i - 1, j, deletes_count - 1) - th元素的情况 基本情况是i(它对应于空前缀)。也许应该考虑其他一些极端情况(这取决于实施细节)。

3)f(0, -1, 0) = 0的答案是max(f(array.length, j, k))。 您可以使用标准答案重建技术找到已删除的数字。

4)时间复杂度为0 <= j < array.length,空间复杂度为O(m^4)其中O(m^3)(使用参数m = max(n, k)和{{可以获得更精确的上限1}}但是没有必要)。