【发布时间】:2016-12-08 15:04:00
【问题描述】:
上周在一次采访中,我被问到上述问题,正如预期的那样,我无法正确回答,后来当我检查时,我发现它是一个基于动态编程的算法。我不精通动态编程,但假设我要设计这个算法,那么我应该如何处理它?
假设,我从 MergeSort 等其他分而治之的算法中汲取灵感,并设计如下解决方案:
- 将序列分成相等的两半。
- 找出两半中最长的递增子序列
- 加入两半。
明明还有缺的,怎么从这里往前走呢?
【问题讨论】:
-
我不明白,您只想在任何给定问题上应用随机想法并使其发挥作用?这个问题可以通过多种方式解决,但只有少数是自然的,动态编程就是其中之一,虽然显然不是最好的(高效)
-
@Yerken 据我所知,使用 B-search 对 DP 版本进行了改进,实现了 O(nlgn),有没有更有效的 LIS 问题算法?
-
@Yerken 这不是一个随机的想法,分而治之是一种众所周知的技术,其次,我的基本目标是知道锄头来解决对你来说完全陌生的问题。
-
@shole 我相信解决这个问题的效率最高。至少我不知道更快的方法。
-
@shole 假设您正在使用整数,如果您使用 van Emde Boas 树而不是二进制搜索,则可以在 O(n * lg(lg(n))) 时间内完成,并且通过额外的密钥重命名(如here 所述),它可以减少到 O(n * lg(lg(k))) 时间,其中 k 是 LIS 的长度。据我所知,这是已知最快的算法。
标签: algorithm data-structures divide-and-conquer