【问题标题】:How can I find the number of non-decreasing subsequences in an array?如何找到数组中非递减子序列的数量?
【发布时间】:2015-10-02 14:30:16
【问题描述】:

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

例如,如果数组是 {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},所以这是 12 个这样的序列

【问题讨论】:

    标签: arrays algorithm subsequence


    【解决方案1】:

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

    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 步:开始 = 6,当前 = 7,comp 7>6 = true,存储 [7],[6,7]
    第 3 步:开始=6,当前=8,补偿 8>7=true,存储 [8]、[7,8]、[6,7,8]
    第 4 步:start=6,current=4,comp 4>8=false,将 start 设置为当前项目,存储 [4]
    第 5 步:开始 = 4,当前 = 5,comp 5>4 = true,存储 [5],[4,5]
    第 6 步:开始=4,当前=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 制作为二维数组并将每个序列seq 存储在sequences[seq.length] 中。

    【讨论】:

      【解决方案2】:

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

      a[i] 成为您的输入数组。设c[i] 为以a[i] 结尾的非递减子序列的数量。您可以通过查看此类子序列中a[i] 之前的数字来轻松计算c[i]。它可以是在a[i] 之前的任何数字a[j](即j&lt;i不大于(a[j]&lt;=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。它只查找最长的序列,但我想它也可以修改为计算所有此类序列。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-14
        • 1970-01-01
        • 2014-03-10
        • 1970-01-01
        相关资源
        最近更新 更多