c[i] < (c[i-1] + c[i+1]) / 2
C[i-1]
、C[i]
和C[i+1]
是子序列中的三个连续元素。
例如,如果输入数组为{1,2,-1,0,3,8,5}
,则最长凸子序列应为:{1,-1,0,3,8}
或{2,-1,0,3,8}
。
在“最长递增子序列”(LIS)问题中,我尝试用同样的动态规划思想来解决这个问题。但是由于子序列中的每个元素都依赖于前面的两个元素,所以O(n^2)解似乎是不可能的。谢谢你的帮助。
这里是O(N2log N)算法(因为log N
之所以在这里是因为排序,所以我们可以将其简化为O(N2log log N),甚至可以通过不同的排序算法或更高级的优先级队列简化为O(N2)):
p[]
。每对中的元素按其索引排序。y2-y1
。如果Y2-Y1
值相等,则它们应按第二个索引的递减顺序排序。L[]
。n-1.P[]
中的每个对的
L[X2]=max(L[X2],L[X1]+1)
。其中x
是输入数组中元素的索引。L[]
中查找最大值。这是最长凸子序列的长度。L[X2]
时,我们将创建一个节点,指向对应于X1
的条目所指向的节点,然后将对应于X2
的条目指向此新节点:bp_head[X2]=新节点(bp_head[X1])
。凸性C[i]<(C[i-1]+C[i+1])/2
可转化为等价不等式C[i]-C[i-1]
该算法的这种简化变体需要O(n2)空间。如果不使用大数组
P[]
,而是使用输入数组S[]
的预排序副本和优先级队列,则空间复杂度可能会降低。步骤#4从这个优先级队列的顶部接收元素。为了保持这个优先级队列的大小等于N,我们只能在s[i]-s[j]
被移除之后才将元素s[i+1]-s[j]
推送到队列中(因此队列只为每个j
保留一个元素)。如果我们使用已知的DP技巧,只存储指向原始后指针链“中间”的一个后指针(针对每个索引)(然后对这个“中间”后指针之前和之后的两个子数组递归地重复此算法),那么后指针森林所消耗的巨大空间就不需要了。
和O(n3)算法:
- 构造图,其中每个顶点对应于数组元素对(按索引排序)。
- 如果顶点有一个公共数组元素,该元素位于与这些顶点相关联的其余两个元素之间,并且所有三个元素都满足凸性,则将顶点与边连接。此边应指向索引较大的顶点。
- 添加源节点和目标节点,并将它们连接到每个顶点。
- 查找此图形中的最长路径。
该图有O(n2)个顶点和O(n3)条边。它可以在O(n3)时间内构造;而且由于它是DAG,寻找最长路径也需要O(n3)的时间。
这里,在这段代码中,它打印序列的最大子序列的长度,该序列先增加后减少,或者反之亦然。 例如: 输入:1,11,2,10,4,5,2,1 如增-减-增或减-增-减 示例: 投入:7 16 1 6 20 17 7 18 25 1 25 21 11 5 29 11 3 3 26 19
然而,我意识到我真正想解决的问题有点不同。给定一个固定的k,我需要确保公共子序列只涉及长度正好为k的子串。例如,设置k=2,并让这两个字符串为 我需要的子序列是“。 是否可以修改动态规划解来解决这个问题?
我已经实现了最长公共子序列算法,并获得了最长的正确答案,但无法找出打印出组成最长公共子序列的方法。 也就是说,我成功地获得了最长公共子序列数组的长度,但我想打印出最长的子序列。 这个代码的操场在这里 http://play.golang.org/p/0sKb_OARnf 当我尝试在标签得到更新时打印出子序列时,结果是重复的。我想为str1和str2打印出类似“GTABTABTABTAB”的东西 提
如何加快以下问题陈述的执行速度?我有一个正确的解决方案,通过每一个测试的小输入。但是,它超过了较大输入的时间限制。我当前的实现是数组大小的二次型。 你的答案应该是基于1的,这意味着数组的第一个位置是1而不是0。 实施
在最多一个序列存在重复的情况下,可以将最长公共子序列问题转化为最长递增子序列问题。减少问题的过程说明在这里: 假设您有以下序列: 然后,创建一个整数序列S3,其中您必须将S2的每个元素的位置放在S1中(如果元素在S1中不存在,那么忽略那个元素)。在本例中: 这种方法是如何工作的?为什么这种约简解决了寻找最长公共子序列的问题?
我的问题是,这个问题有没有更好的解决办法?多谢.