【问题标题】:Algorithm to find length of a minimal sub-array containing all the elements of an array/vector查找包含数组/向量的所有元素的最小子数组的长度的算法
【发布时间】:2019-11-17 05:19:24
【问题描述】:

假设我们有一个数组 {7, 3, 7, 3, 1, 3, 4, 1}。 我需要的是一种算法(最好是一些 C++ 代码示例),它将返回 包含所有数组元素的最小子数组的长度

在这种情况下,它将是 5: {7, 3, 1, 3, 4},这是原始数组的最短子数组,其中包含数组的所有元素,即 1、3、4和 7.

另外,还有一个数组 {2, 1, 1, 3, 2, 1, 1, 3} 的示例,算法应该返回 3,因为我们要查找的子数组是 {1, 3, 2} (原始数组的索引 2-4)。

我在这里发现了一些类似的问题:Find minimum length of sub-list containing all elements of a list 但它似乎没有回答。

函数签名应该是这样的: int algorithm(std::vector<int> &arr){...}

【问题讨论】:

  • 看看“最长公共子序列”。算法。它最初用于字符串,但也可以适应您的问题。
  • 你到底卡在哪里了?你有更具体的问题吗?你还在为 C++ 苦苦挣扎吗?您不确定无论语言如何,该算法都将如何工作?你试过什么?
  • 我在 C++ 实现方面苦苦挣扎。我需要具有给定签名的 C++ 代码。
  • 那太宽泛了。你到底在挣扎什么?您能否添加您拥有的代码并指出您的问题所在?

标签: arrays algorithm distinct-values sub-array


【解决方案1】:

在 O(n) 中找到最后一个子数组:

例如,对于数组[1, 2, 3, 2, 2, 1, 1],获取哈希表/映射(或小范围数组)中项目的计数:{ 1: 3, 2: 3, 3: 1 }

要找到子数组的起始索引,从数组中的第一个值开始,检查它的计数是否大于1。如果计数大于1,则将它的计数减一,并继续下一个值直到一个计数为 1 的值。向后重复相同的操作以找到子数组的最后一个索引:

1, 2, 3, 2, 2, 1, 1
      ^        ^

在 O(n) 中找到其余的子数组:

现在要检查它是否是最小子数组,检查它之前的子数组。为此,在第一个索引之前搜索位于最后一个索引处的值 1 的最后一个索引。如果找到,将第一个索引更改为它,并将最后一个索引减一:

1, 2, 3, 2, 2, 1, 1
^           ^

现在要找到新子数组的最后一个索引,在第一个和最后一个索引之间搜索位于最后一个索引处的值 2,并将最后一个索引更改为它:

1, 2, 3, 2, 2, 1, 1
^        ^  

重复直到在第一个和最后一个索引之间找不到最后一个索引处的值:

1, 2, 3, 2, 2, 1, 1
^     ^  

现在检查新子数组的计数是否小于前一个子数组的计数,如果需要,更新当前最小子数组的索引。

必须重复搜索其余子数组,直到在第一个索引之前找不到最后一个索引处的值。

【讨论】:

    猜你喜欢
    • 2016-09-08
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    • 1970-01-01
    • 2019-01-22
    • 2017-01-17
    相关资源
    最近更新 更多