【问题标题】:Find longest series of ones in a binary digit array在二进制数字数组中查找最长的系列
【发布时间】:2011-12-01 11:22:44
【问题描述】:

如何在这个二进制数字数组中找到最长的系列 - 100011101100111110011100

在这种情况下,答案应该是 = 11111

我正在考虑循环遍历数组并检查每个数字,如果数字是 1,则将其添加到新字符串中,如果为零则重新开始创建新字符串,但保存之前创建的字符串。完成后检查每个字符串的长度,看看哪个是最长的。我确定有更简单的解决方案?

【问题讨论】:

  • 当然可以,但前提是您实际上没有二进制数字数组。
  • 仅供参考,我刚刚在这里发布了一个更有效的算法:stackoverflow.com/a/10922528/477037。它是用 Ruby 编写的,但很容易适应。

标签: java regex algorithm


【解决方案1】:

您的算法很好,但您不需要保存所有临时字符串 - 反正它们都是“一”。

您应该只有两个变量“bestStartPosition”和“bestLength”。找到“ones”序列后 - 将此序列的长度与保存的“bestLength”进行比较,并用新的位置和长度覆盖这两个变量。

扫描完所有数组后,您将获得最长序列的位置(以备不时之需)和长度(通过它您可以生成一串“ones”)。

【讨论】:

    【解决方案2】:

    Java 8 更新,时间复杂度为 O(n)(并且只有 1 行):

    int maxLength = Arrays.stream(bitStr.split("0+"))
      .mapToInt(String::length)
      .max().orElse(0);
    

    live demo

    这也会自动处理空白输入,在这种情况下返回0


    Java 7 紧凑的解决方案,但 O(n log n) 时间复杂度:

    让 java API 只需 3 行即可为您完成所有工作:

    String bits = "100011101100111110011100";
    
    LinkedList<String> list = new LinkedList<String>(Arrays.asList(bits.split("0+")));
    Collections.sort(list);
    int maxLength = list.getLast().length(); // 5 for the example given
    

    这是如何工作的:

    1. bits.split("0+") 将输入分解为 String[],每个连续的 1 链(由全零分隔 - 正则表达式为 0+)成为数组的一个元素
    2. Arrays.asList()String[] 变成 List&lt;String&gt;
    3. 从刚刚创建的列表中创建并填充一个新的LinkedList
    4. 使用集合对列表进行排序。最长的 1 链将排在最后
    5. 获取列表中最后一个元素(最长)的长度。这就是选择 LinkedList 的原因 - 它有一个 getLast() 方法,我认为这很方便

    对于那些认为这“太繁重”的人来说,在我的 MacBook Pro 上执行示例输入所需的时间不到 1 毫秒。除非您输入的字符串是千兆字节长,否则此代码将执行得非常快。

    已编辑

    Max 建议,使用Arrays.sort() 非常相似,执行时间减半,但仍需要 3 行代码:

    String[] split = bits.split("0+");
    Arrays.sort(split);
    int maxLength = split[split.length - 1].length();
    

    【讨论】:

    • 你可以使用Arrays.sort()来简化它
    • @Max 我喜欢 - 见编辑! (但令人失望的是它并没有更紧凑)
    • 好吧,你总是可以将代码堆叠在 1 行中以使其更“紧凑”:D
    • 我喜欢,这个的时空复杂度是多少?
    • @jalal 时间复杂度 O(n log n) 由于排序,但我添加了一个 O(n) 且更优雅的 Java 8 解决方案.
    【解决方案3】:

    这里有一些伪代码可以做你想做的:

    count = 0
    longestCount = 0
    foreach digit in binaryDigitArray:
       if (digit == 1) count++
       else:
          longestCount = max(count, maxCount)
          count = 0
    longestCount = max(count, maxCount)
    

    更简单的方法是提取所有 1 的序列,按长度排序并选择第一个。但是,根据使用的语言,这可能只是我建议的简短版本。

    【讨论】:

      【解决方案4】:

      只有一些php的预览代码,也许你可以重写成你的语言。

      这将说明 1 的最大长度是多少:

      $match = preg_split("/0+/", "100011101100111110011100", -1, PREG_SPLIT_NO_EMPTY);
      echo max(array_map('strlen', $match));
      

      结果:

       5
      

      【讨论】:

      • 看起来不错,但对于这样一个简单的任务来说,CPU 和内存是多余的。
      • 至少通过写“/0+/”而不是“/0/”来优化它。将导致更少的分裂。
      猜你喜欢
      • 2018-08-03
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-25
      • 2014-10-03
      相关资源
      最近更新 更多