#include <iostream>
#include <vector>
//Find Majority element i.e. the element that occurs more than 1/2 of the array
// Worst Case Complexity : O(n)
template <typename DataType>
DataType FindMajorityElement(std::vector<DataType> arr) {
// Modified BOYERS ALGORITHM with forward and reverse passes
// Count will stay positive if there is a majority element
auto GetMajority = [](auto seq_begin, auto seq_end) -> DataType{
int count = 1;
DataType majority = *(seq_begin);
for (auto itr = seq_begin+1; itr != seq_end; ++itr) {
count += (*itr == majority) ? 1 : -1;
if (count <= 0) { // Flip the majority and set the count to zero whenever it falls below zero
majority = *(itr);
count = 0;
}
}
return majority;
};
DataType majority1 = GetMajority(arr.begin(), arr.end());
DataType majority2 = GetMajority(arr.rbegin(), arr.rend());
int maj1_count = 0, maj2_count = 0;
// Check if any of the the majority elements is really the majority
for (const auto& itr: arr) {
maj1_count += majority1 == itr ? 1 : 0;
maj2_count += majority2 == itr ? 1 : 0;
}
if (maj1_count >= arr.size()/2)
return majority1;
if (maj2_count >= arr.size()/2)
return majority2;
// else return -1
return -1;
}
int main() {
using namespace std;
std::cout << FindMajorityElement(std::vector<int> { 1, 10, 2, 10, 1, 10, 4, 10, 5, 10 }) << endl;
std::cout << FindMajorityElement(std::vector<int> { 10, 1, 10, 2, 10, 1, 10, 4, 10, 5 }) << endl;
std::cout << FindMajorityElement(std::vector<int> { 1, 2, 1, 10, 10, 10, 10, 4, 10, 5 }) << endl;
std::cout << FindMajorityElement(std::vector<int> { 1, 1, 1, 10, 10, 10, 10, 10, 5, 4 }) << endl;
std::cout << FindMajorityElement(std::vector<float> { 1.0f, 1.0f, 1.0f, 10.f, 10.0f, 10.0f, 10, 10, 5, 4 }) << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgoKLy9GaW5kIE1ham9yaXR5IGVsZW1lbnQgaS5lLiB0aGUgZWxlbWVudCB0aGF0IG9jY3VycyBtb3JlIHRoYW4gMS8yIG9mIHRoZSBhcnJheQovLyBXb3JzdCBDYXNlIENvbXBsZXhpdHkgOiAgTyhuKQp0ZW1wbGF0ZSA8dHlwZW5hbWUgRGF0YVR5cGU+CkRhdGFUeXBlIEZpbmRNYWpvcml0eUVsZW1lbnQoc3RkOjp2ZWN0b3I8RGF0YVR5cGU+IGFycikgewogICAgLy8gTW9kaWZpZWQgQk9ZRVJTIEFMR09SSVRITSB3aXRoIGZvcndhcmQgYW5kIHJldmVyc2UgcGFzc2VzCiAgICAvLyBDb3VudCB3aWxsIHN0YXkgcG9zaXRpdmUgaWYgdGhlcmUgaXMgYSBtYWpvcml0eSBlbGVtZW50CiAgICBhdXRvIEdldE1ham9yaXR5ID0gW10oYXV0byBzZXFfYmVnaW4sIGF1dG8gc2VxX2VuZCkgLT4gRGF0YVR5cGV7CiAgICAgICAgaW50IGNvdW50ID0gMTsKICAgICAgICBEYXRhVHlwZSBtYWpvcml0eSA9ICooc2VxX2JlZ2luKTsKICAgICAgICBmb3IgKGF1dG8gaXRyID0gc2VxX2JlZ2luKzE7IGl0ciAhPSBzZXFfZW5kOyArK2l0cikgewogICAgICAgICAgICBjb3VudCArPSAoKml0ciA9PSBtYWpvcml0eSkgPyAxIDogLTE7CiAgICAgICAgICAgIGlmIChjb3VudCA8PSAwKSB7ICAgLy8gRmxpcCB0aGUgbWFqb3JpdHkgYW5kIHNldCB0aGUgY291bnQgdG8gemVybyB3aGVuZXZlciBpdCBmYWxscyBiZWxvdyB6ZXJvCiAgICAgICAgICAgICAgICBtYWpvcml0eSA9ICooaXRyKTsKICAgICAgICAgICAgICAgIGNvdW50ID0gMDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFqb3JpdHk7CiAgICB9OwogICAgRGF0YVR5cGUgbWFqb3JpdHkxID0gR2V0TWFqb3JpdHkoYXJyLmJlZ2luKCksIGFyci5lbmQoKSk7CiAgICBEYXRhVHlwZSBtYWpvcml0eTIgPSBHZXRNYWpvcml0eShhcnIucmJlZ2luKCksIGFyci5yZW5kKCkpOwogICAgaW50IG1hajFfY291bnQgPSAwLCBtYWoyX2NvdW50ID0gMDsKICAgIC8vIENoZWNrIGlmIGFueSBvZiB0aGUgdGhlIG1ham9yaXR5IGVsZW1lbnRzIGlzIHJlYWxseSB0aGUgbWFqb3JpdHkKICAgIGZvciAoY29uc3QgYXV0byYgaXRyOiBhcnIpIHsKICAgICAgICBtYWoxX2NvdW50ICs9IG1ham9yaXR5MSA9PSBpdHIgPyAxIDogMDsKICAgICAgICBtYWoyX2NvdW50ICs9IG1ham9yaXR5MiA9PSBpdHIgPyAxIDogMDsKICAgIH0KICAgIGlmIChtYWoxX2NvdW50ID49IGFyci5zaXplKCkvMikKICAgICAgICByZXR1cm4gbWFqb3JpdHkxOwogICAgaWYgKG1hajJfY291bnQgPj0gYXJyLnNpemUoKS8yKQogICAgICAgIHJldHVybiBtYWpvcml0eTI7CiAgICAvLyBlbHNlIHJldHVybiAtMQogICAgcmV0dXJuIC0xOwp9CgppbnQgbWFpbigpIHsKICAgIHVzaW5nIG5hbWVzcGFjZSBzdGQ7CiAgICBzdGQ6OmNvdXQgPDwgIEZpbmRNYWpvcml0eUVsZW1lbnQoc3RkOjp2ZWN0b3I8aW50PiB7IDEsIDEwLCAyLCAxMCwgMSwgMTAsIDQsIDEwLCA1LCAxMCB9KSA8PCBlbmRsOwogICAgc3RkOjpjb3V0IDw8ICBGaW5kTWFqb3JpdHlFbGVtZW50KHN0ZDo6dmVjdG9yPGludD4geyAxMCwgMSwgMTAsIDIsIDEwLCAxLCAxMCwgNCwgMTAsIDUgfSkgPDwgZW5kbDsKICAgIHN0ZDo6Y291dCA8PCAgRmluZE1ham9yaXR5RWxlbWVudChzdGQ6OnZlY3RvcjxpbnQ+IHsgMSwgMiwgMSwgMTAsIDEwLCAxMCwgMTAsIDQsIDEwLCA1IH0pIDw8IGVuZGw7CiAgICBzdGQ6OmNvdXQgPDwgIEZpbmRNYWpvcml0eUVsZW1lbnQoc3RkOjp2ZWN0b3I8aW50PiB7IDEsIDEsIDEsIDEwLCAxMCwgMTAsIDEwLCAxMCwgNSwgNCB9KSA8PCBlbmRsOwogICAgc3RkOjpjb3V0IDw8ICBGaW5kTWFqb3JpdHlFbGVtZW50KHN0ZDo6dmVjdG9yPGZsb2F0PiB7IDEuMGYsIDEuMGYsIDEuMGYsIDEwLmYsIDEwLjBmLCAxMC4wZiwgMTAsIDEwLCA1LCA0IH0pIDw8IGVuZGw7CiAgICByZXR1cm4gMDsKfQoK