如何找到数组中非递减子序列的数量?

时间:2015-10-02 14:30:16

标签: arrays algorithm subsequence

给定一组正整数,我想找出数组中非递减子序列的数量。

例如,如果数组为{6,7,8,4,5,6},则非递减子序列为{6},{7},{8},{4},{5},{6},{6,7},{7,8},{4,5},{5,6},{6,7,8},{4,5,6},以便这样的序列

2 个答案:

答案 0 :(得分:2)

这是一个算法,它将列出一系列数字中的每个上升子序列:

Set a pointer to the first item, to remember where the rising sequence starts.
Iterate over every item in the array, and for each item:  
    If the current item is not greater than the previous item:  
        Set the pointer to the current item.
    For every n = 1, 2, 3... :
        Save the last n items as a sequence until you reach the pointer.

使用示例输入[6,7,8,4,5,6]运行此算法将是:

  

步骤1:开始= 6,当前= 6,存储[6]
  步骤2:start = 6,current = 7,comp 7> 6 = true,存储[7],[6,7]
  步骤3:start = 6,current = 8,comp 8> 7 = true,存储[8],[7,8],[6,7,8]
  步骤4:start = 6,current = 4,comp 4> 8 = false,将start设置为当前项,store [4]
  步骤5:start = 4,current = 5,comp 5> 4 = true,存储[5],[4,5]
  步骤6:start = 4,current = 6,comp 6> 5 = true,存储[6],[5,6],[4,5,6]

     

结果:[6],[7],[6,7],[8],[7,8],[6,7,8],[4],[5],[4,5] ,[6],[5,6],[4,5,6]

例如在javascript:中(注意:slice()函数用于创建数组的硬拷贝)

function rising(array) {
    var sequences = [], start = 0;
    for (var current = 0; current < array.length; current++) {
        var seq = [], from = current;
        if (array[current] < array[current - 1]) start = current;
        while (from >= start) {
            seq.unshift(array[from--]);
            sequences.push(seq.slice());
        }
    }
    return sequences;
}

var a = rising([6,7,8,4,5,6]);
document.write(JSON.stringify(a));

如果您希望按照您在问题中编写的顺序显示结果:[6],[7],[8],[4],[5],[6],[6,7],[7,8],[4,5],[5,6],[4,5,6],[6,7,8],则将sequences设为2D数组,并将每个序列seq存储在sequences[seq.length]中。< / p>

答案 1 :(得分:0)

您可以使用类似于well-known quadratic solution for the longest increasing subsequence的动态编程方法。

a[i]成为您的输入数组。设c[i]为以a[i]结尾的非递减子序列的数量。您可以通过查看此类子序列中c[i]之前的数字来轻松计算a[i]。它可以是a[j]之前的任何数字a[i](即j<i不是更高(a[j]<=a[i])。不要忘记单元素子序列{a[i]}。这导致以下伪代码:

c[0] = 1
for i = 1..n-1
    c[i] = 1 // the one-element subsequence
    for j = 0..i-1 
        if a[j]<=a[i]
            c[i] += c[j]

另见Number of all longest increasing subsequences。它只查找最长的序列,但我想它可以修改为计算所有这些序列。