如何在数组中找到最长的不同(!)元素行?
我们有一个矩阵 我们的任务是在这个矩阵中找到一行,其中是不同元素的最长行
例如 0 1 2 3 4 1 2 3 应该计数0 1 2 3 4 = 5个元素
答案 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:尽管可能有一个步骤可以删除多个列表项(来自每个数据结构),但每个项最多只能进入和离开一次。
示例强>
以下是某个步骤中两个数据结构的示例。灰色地图引用蓝色链接列表中的项目。
现在明确的长度是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)中执行此操作。