How do you find the longest row of different(!) elements in an array?
We have a matrix Our task is to find a row in this matrix where is the longest row of different elements
For example 0 1 2 3 4 1 2 3 Should count 0 1 2 3 4 = 5 elements
How do you find the longest row of different(!) elements in an array?
We have a matrix Our task is to find a row in this matrix where is the longest row of different elements
For example 0 1 2 3 4 1 2 3 Should count 0 1 2 3 4 = 5 elements
Try to use Kadane's algorithm described here: Maximum Subarray Problem
Just replace sum operation with adding-to-set and find-in-set operations. So, you is able to create a O(n) algo.
This is my try:
#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;
}
Gives output:
Index = 3 Length = 4
Suppose you use two data structures:
a std::list
of integers
a std::unordered_map
mapping integers into iterators of the list
Now operate as follows. When you encounter the next integer, check if it is in the unordered map.
If it is, find the corresponding iterator in the list, and remove it and all items left of it (from both list and unordered map)
If it is not, add it to the list, and set the unordered map to point at it
Furthermore, at each step, track both the step index, and the size of the unordered map (or the list). Output the index of the largest size, at the end.
This algorithm is amortized expected linear time: although there might be a step that removes more than a single list item (from each of the data structures), each item enters and leaves them at most once.
Example
Here is an example of the two data structures at some step. The grey map references items in the blue linked list.
The distinct length is now 4. If 2 is now encountered, however, then it and the link(s) left of it (in this case 3) will be purged before it is added, and the length will be reduced to 3.
Try something like this:
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
It is not very elegant solution, but it works
You can do this in O(n) using a caterpillar algorithm.