【问题标题】:Finding the longest down sequence in a Java array在 Java 数组中查找最长的向下序列
【发布时间】:2010-10-07 01:35:25
【问题描述】:

给定这个数组

int [] myArray = {5,-11,2,3,14,5,-14,2};

我必须能够返回 3,因为最长的向下序列是 14,5,-14。 最快的方法是什么?

PS:向下序列是一系列不递增的数字。

【问题讨论】:

  • 你确定子序列的元素一定是连续的吗?因为那会改变答案。请参阅Longest increasing subsequence 问题。
  • 似乎它们必须是连续的才能被视为一个序列?
  • 为什么需要最快的方式?
  • @tony 这是一个学校作业。 @bill 数组不需要固定,你可以自己放入。
  • @Derek 我们的意思是,根据您的问题定义,[5, -11, -14] 是否被视为有效的“向下序列”?

标签: java arrays algorithm sequence


【解决方案1】:

python 中的另一个实现:

def longest_down_sequence(seq):
    max = 0
    current_count = 0
    last = None
    for x in seq:
        if x <= last: current_count += 1
        else: current_count = 1
        if current_count > max: max = current_count
        last = x
    return max

【讨论】:

  • 啊,是的,我忘了在我的回答中提到,如果你不关心最后 在哪里子序列发生了,你可以保存两个变量。
  • 题外话——我刚开始学习python,所以这个例子是一个很好的掌握循环的例子!谢谢。
  • 是的,for 在现实中是一个 for-each。如果你想像往常一样做“for x in range[0,len(seq)]”然后你可以做一些事情到 seq[x]
【解决方案2】:

只需遍历数字列表即可。伪代码:

bestIndex = 0
bestLength = 0

curIndex = 0
curLength = 1

for index = 1..length-1
   if a[index] is less than or equal to a[index-1]
       curLength++
   else 
       //restart at this index since it's a new possible starting point
       curLength = 1
       curIndex = index

   if curLength is better than bestLength
       bestIndex = curIndex
       bestLength = curLength

next          

注意:如果您不关心知道该子序列出现的位置,您可以放弃任何包含 bestIndex 或 curIndex 的行,如 Gary 的实现中所见。

【讨论】:

  • 他说“不增加”,这会找到最长的减少序列的长度。
  • 感谢@oksayt,已更正。我认为这不会改变算法,只是比较。
  • 反例 [1,1,0,1,1] 最长的不增加是 4 long,你的算法返回 3。
  • @piccolbo:我不明白......你从 0 增加到 1。你认为 4 长度的子序列是什么?也许我不明白这个问题,但你的“反例”对我来说毫无意义。
  • 哦,我明白了,你对这个问题有不同的解释。我认为没有任何证据可以证明您的解释,在 OP 给出的示例中给出了许多不同的非连续序列较早出现;他竭尽全力将连续序列作为示例解决方案。跨度>
【解决方案3】:

在java中:

    int [] myArray = {5,-11,2,3,14,5,-14,2};
    int downSequence = 1;
    int longestDownSequence = 1;
    for(int i = 1; i < myArray.length; i++) {
        if(myArray[i] <= myArray[i-1]) downSequence++;
        else {
            if(downSequence > longestDownSequence)
                longestDownSequence = downSequence;
            downSequence = 1;
        }
    }
    if(downSequence > longestDownSequence)
        longestDownSequence = downSequence;
    System.out.println(longestDownSequence);

由于您要求最快或更好的性能,请仅在重置计数器之前检查最长的下行序列。永远不要在每次迭代中。但是,您必须在循环后再次检查,以防最长的序列位于数组的末尾。

【讨论】:

  • 这也是我的,提交给我的学校自动标记,没有通过,我想我们错过了一些我们没有在这里处理的案例
  • 我唯一能想到的是它是否是一个空数组。那么它应该返回零吗?
  • 顺便说一句,我编辑了代码以根据您的定义将等于序列作为向下序列包含在内。我错过了那个。
  • 我特别没有用java写我的答案,因为它看起来像一个简单的家庭作业问题:-)。
【解决方案4】:

Java 中的另一种解决方案:

static int[] longestDownSequenceList(int[] array) {

    if (array.length <= 1) {
        return array;
    }

    int maxSize = 1; 
    int maxEnd = 0; 

    int curSize = 1;

    for (int i = 1; i < array.length; i++) {

        if (array[i] < array[i-1]) {
            curSize++;

            if (curSize > maxSize) {
                maxSize = curSize; 
                maxEnd = i;
            }
        }
        else {               
            curSize = 1;
        }
    }

    return Arrays.copyOfRange(array, maxEnd-maxSize+1, maxEnd+1);
}

【讨论】:

    【解决方案5】:

    正如上面的比尔所说,这基本上是最长的递增子序列。有关最佳解决方案,请参阅 wikipedia 条目。这是从那里引用的,对非递减情况进行了一些小改动

     L = 0
     for i = 1, 2, ... n:
        binary search for the largest positive j ≤ L such that X[M[j]] >= X[i] (or set j = 0 if no such value exists)
        P[i] = M[j]
        if j == L or X[i] >= X[M[j+1]]:
           M[j+1] = i
           L = max(L, j+1)
    

    请参阅我上面评论中其他建议解决方案的反例。

    【讨论】:

    • 不同的解释,但考虑到 OP 给出的示例输入和输出,我想说没有更多的证据证明这就是他正在寻找的东西。看我的回答。
    【解决方案6】:

    最快的方法可能取决于环境:计算机和问题大小。

    对于非常大的列表(或数组),并行化作业可能很有用,可以实现:

    • 拆分和拆分并将列表拆分为简单元素。
    • 如果可能,将向下序列(或非递增)的元素粘合到块中,并将块粘合在一起。
    • 搜索最长的块。

    【讨论】:

      猜你喜欢
      • 2014-10-03
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 2018-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多