【问题标题】:Longest subsequence with alternating increasing and decreasing values具有交替递增和递减值的最长子序列
【发布时间】:2012-09-09 21:14:39
【问题描述】:

给定一个数组,我们需要找到具有交替递增和递减值的最长子序列的长度。

例如,如果数组是 , 7 4 8 9 3 5 2 1 然后是 L = 67,4,8,3,5,27,4,9,3,5,1 等。

也可能是先有小元素后有大元素的情况。

对此最有效的解决方案是什么?我想到了一个 DP 解决方案。如果我们用蛮力来做,我们会怎么做(O(n^3)?)?

这不是作业问题。

【问题讨论】:

  • 不。我不做SPOJ。更像是 LIS 的一个变体。
  • 你google过最长的双音子序列吗?很多答案...
  • @Kwariz Bitonic 序列是一个先增加然后减少的序列。这里是交替的。
  • @sTEAK 查看算法,将递增的第一算法更改为递减的第一算法是微不足道的。最坏的情况你必须运行它两次

标签: arrays algorithm language-agnostic dynamic-programming


【解决方案1】:

您确实可以在这里使用动态编程方法。为了简单起见,假设我们只需要找到这样的序列 seq 的最大长度(很容易调整解决方案来找到序列本身)。

对于每个索引,我们将存储 2 个值:

  • 交替序列的最大长度在最后一步增加的那个元素处结束(例如,incr[i])
  • 交替序列的最大长度在最后一步减少的那个元素处结束(例如,decr[i])

根据定义,我们也假设incr[0] = decr[0] = 1

那么每个incr[i]都可以递归找到:

incr[i] = max(decr[j])+1, where j < i and seq[j] < seq[i]
decr[i] = max(incr[j])+1, where j < i and seq[j] > seq[i]

所需的序列长度将是两个数组中的最大值,这种方法的复杂度是 O(N*N) 并且需要 2N 的额外内存(其中 N 是初始序列的长度)

c 中的简单示例:

int seq[N]; // initial sequence
int incr[N], decr[N];

... // Init sequences, fill incr and decr with 1's as initial values

for (int i = 1; i < N; ++i){
    for (int j = 0; j < i; ++j){
         if (seq[j] < seq[i]) 
         {
             // handle "increasing" step - need to check previous "decreasing" value
             if (decr[j]+1 > incr[i])  incr[i] = decr[j] + 1;
         }
         if (seq[j] > seq[i]) 
         {
             if (incr[j]+1 > decr[i])  decr[i] = incr[j] + 1;
         }
    }
}

... // Now all arrays are filled, iterate over them and find maximum value

算法将如何工作:

步骤 0(初始值):

seq  = 7   4 8 9 3 5 2 1
incr = 1   1 1 1 1 1 1 1
decr = 1   1 1 1 1 1 1 1

第 1 步在索引 1 ('4') 处取值并检查以前的值。 7 > 4 所以我们做“从索引 0 到索引 1 的递减步长,新的序列值:

incr = 1 1   1 1 1 1 1 1
decr = 1 2   1 1 1 1 1 1

第 2 步。 取值 8 并迭代之前的值:

7

incr = 1 1 2   1 1 1 1 1
decr = 1 2 1   1 1 1 1 1

4

incr = 1 1 3   1 1 1 1 1
decr = 1 2 1   1 1 1 1 1

等等……

【讨论】:

  • 你能试一下你的算法吗?为了更清楚。谢谢。
  • @sTEAK。抱歉,您的意思是添加一些伪代码或其他任何东西? (我的英语让我失望了:()
  • 是的伪代码及其示例。将您的算法应用于示例
  • 在第 2 步中,你为什么要检查 4
  • @sTEAK。由于 4
猜你喜欢
  • 1970-01-01
  • 2016-04-11
  • 2020-06-28
  • 2013-07-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多