找到序列中不同项的最长连续子序列

时间:2016-03-29 22:01:15

标签: c++ algorithm data-structures data-stream

如何在数组中找到最长的不同(!)元素行?

我们有一个矩阵 我们的任务是在这个矩阵中找到一行,其中是不同元素的最长行

例如 0 1 2 3 4 1 2 3 应该计数0 1 2 3 4 = 5个元素

4 个答案:

答案 0 :(得分:5)

尝试使用此处描述的Kadane算法:Maximum Subarray Problem

只需将sum操作替换为add-to-set和find-in-set操作。所以,你可以创建一个O(n)算法。

这是我的尝试:

#include <iostream>
#include <unordered_set>

using namespace std;

int main() {
    int mas[] = {1,2,3,1,2,3,4,1,2};
    size_t count = sizeof(mas)/sizeof(mas[0]);

    size_t best = 0;
    int best_index = 0;
    unordered_set<int> unique;
    for (int i = 0; i < count; i++) {
        while (unique.find(mas[i]) != unique.end()) {
            unique.erase(mas[i - unique.size()]);
        }
        unique.insert(mas[i]);
        if (unique.size() > best) {
            best = unique.size();
            best_index = i - best + 1;
        }
    }

    cout << "Index = " << best_index << " Length = " << best << endl;
}

提供输出:

Index = 3 Length = 4

答案 1 :(得分:1)

假设您使用两种数据结构:

  • std::list整数

  • std::unordered_map映射整数到列表的迭代器

现在操作如下。遇到下一个整数时,请检查它是否在无序映射中。

  • 如果是,在列表中找到相应的迭代器,并删除它及其左边的所有项目(来自列表和无序映射)

  • 如果不是,请将其添加到列表中,并将无序地图设置为指向

此外,在每个步骤中,跟踪步骤索引和无序映射(或列表)的大小。最后输出最大尺寸的索引。

此算法的预期线性时间为amortized:尽管可能有一个步骤可以删除多个列表项(来自每个数据结构),但每个项最多只能进入和离开一次。

示例

以下是某个步骤中两个数据结构的示例。灰色地图引用蓝色链接列表中的项目。

enter image description here

现在明确的长度是4.如果现在遇到2,那么它和它左边的链接(在这种情况下为3)将在添加之前被清除,并且长度将减少到3。

答案 2 :(得分:0)

尝试这样的事情:

  const int len = 4;
  int arr[len][len] = {{1, 2, 2, 2}, {3, 2, 3, 5}, {2, 4, 3, 6}, {1, 1, 1, 1}};
  int max = -1, current = 1;
  for (int i = 0; i < len; i++) {
    for (int j = 1; j < len; j++) {
      if (arr[i][j] != arr[i][j - 1]) {
        current++;
      } else {
        if (current > max) {
          max = current;
        }
        current = 1;
      }
    }
    if (current > max) {
      max = current;
    }
    current = 1;
  }
  // output max      

这不是一个非常优雅的解决方案,但它有效

答案 3 :(得分:0)

您可以使用Caterpillar算法在O(n)中执行此操作。

  • 头部和尾部指针始于同一位置。你移动头部并添加一个哈希集(如果它还没有)。
  • 如果头部无法移动,请移动尾部。从哈希集中删除相应的数字。
  • 当你一直走的时候,看看是否有新的最大长度。
  • 头部和尾部各自位于每个位置一次,因此它是O(n)