我想最大化数组中之字形序列的数量(无需重新排序)。
我有一个随机整数整数的主数组。我想要一个具有锯齿形图案的主数组的索引子数组。
一个整数序列如果其每个元素严格小于或严格大于其邻居(和两个相邻邻居),则称为之字形序列。
示例:序列4 2 3 1 5 2形成锯齿形,但是7 3 5 5 2和3 8 6 4 5 和4 2 3 1 5 3不会。
对于给定的整数数组,我们需要找到形成锯齿形序列的索引的(连续)子数组。
这可以在O(N)中完成吗?
答案 0 :(得分:0)
是的,这似乎可以在O(n)时间内解决。我将算法描述为动态程序。
将包含潜在之字形的数组称为Z
。
让U
是一个数组,使得len(U) == len(Z)
和U[i]
是一个整数,代表从i
开始的最大连续的从左到右的子序列,它是Z字形-zag这样Z[i] < Z[i+1]
(它向上弯曲)。
让D
与U
类似,不同的是D[i]
是一个整数,代表从i
开始的最大连续的从左到右子序列,它是Z字形,像Z[i] > Z[i+1]
一样弯曲(向下弯曲)。
子问题是在每个U[i]
处同时找到D[i]
和i
。可以按照以下步骤进行操作:
U[i] = {
1 + D[i+1] if i < i+1
0 otherwise
}
L[i] = {
1 + U[i+1] if i > i+1
0 otherwise
}
最上面的版本说,如果我们要寻找一个最大的序列(以up-zig开头),我们将查看下一个元素是否更大(向上),然后在下一个down的大小中添加一个zig -zag序列。下一个是相反的。
如果i == len(Z)
(它是最后一个元素),则U[i] = L[i] = 0
。最后一个元素后面不能有从左到右的顺序,因为后面没有任何内容。
要获得解决方案,首先我们为每个max(U[i])
找到max(L[i])
和i
。然后获取这两个值中的最大值,存储i
,并存储此最大之字形的长度(在名为length
的变量中)。该序列从索引i
开始,到索引i + length
结束。
有n个索引,因此在U
和L
之间有2n个子问题。给定先前解决的子问题的解决方案,每个子问题都需要O(1)时间来解决。最后,迭代U
和L
以获得最终答案需要O(2n)时间。
因此,我们有O(2n)+ O(2n)时间或 O(n)。
这可能是一个过于复杂的解决方案,但它表明可以在O(n)中完成。