114 lines
2.9 KiB
C++
114 lines
2.9 KiB
C++
#include <iostream>
|
|
#include <vector>
|
|
#include <list>
|
|
|
|
// A minimal separate-chaining HashSet for integers.
|
|
class MyHashSet {
|
|
private:
|
|
std::vector< std::list<int> > table;
|
|
int num_elements;
|
|
static const int DEFAULT_SIZE = 16;
|
|
static const double LOAD_FACTOR_THRESHOLD;
|
|
|
|
int hashFunction(int key) const {
|
|
int h = key < 0 ? -key : key; // handle negative
|
|
return h % (int)table.size();
|
|
}
|
|
|
|
void rehash() {
|
|
int newSize = (int)table.size() * 2;
|
|
std::vector< std::list<int> > newTable(newSize);
|
|
|
|
for (auto &chain : table) {
|
|
for (int val : chain) {
|
|
int h = (val < 0 ? -val : val) % newSize;
|
|
newTable[h].push_back(val);
|
|
}
|
|
}
|
|
table.swap(newTable);
|
|
}
|
|
|
|
void rehashIfNeeded() {
|
|
double load_factor = (double)num_elements / (double)table.size();
|
|
if (load_factor > LOAD_FACTOR_THRESHOLD) {
|
|
rehash();
|
|
}
|
|
}
|
|
|
|
public:
|
|
MyHashSet(int initialSize = DEFAULT_SIZE)
|
|
: table(initialSize), num_elements(0) {}
|
|
|
|
bool find(int key) const {
|
|
int h = hashFunction(key);
|
|
for (int val : table[h]) {
|
|
if (val == key) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void insert(int key) {
|
|
if (!find(key)) {
|
|
int h = hashFunction(key);
|
|
table[h].push_back(key);
|
|
num_elements++;
|
|
rehashIfNeeded();
|
|
}
|
|
}
|
|
};
|
|
|
|
const double MyHashSet::LOAD_FACTOR_THRESHOLD = 1.0;
|
|
|
|
int longestConsecutive(std::vector<int>& nums) {
|
|
if (nums.empty()) return 0;
|
|
|
|
// Insert all numbers into the custom hash set
|
|
MyHashSet set;
|
|
for (int n : nums) {
|
|
set.insert(n);
|
|
}
|
|
|
|
int longestStreak = 0;
|
|
// For each number, only count a sequence if it's a "start"
|
|
// i.e., if (n-1) is NOT in the set
|
|
for (int n : nums) {
|
|
if (!set.find(n - 1)) {
|
|
// n is the start of a consecutive sequence
|
|
int currentNum = n;
|
|
int currentStreak = 1;
|
|
|
|
while (set.find(currentNum + 1)) {
|
|
currentNum++;
|
|
currentStreak++;
|
|
}
|
|
if (currentStreak > longestStreak) {
|
|
longestStreak = currentStreak;
|
|
}
|
|
}
|
|
}
|
|
|
|
return longestStreak;
|
|
}
|
|
|
|
int main() {
|
|
// You can change these test vectors to experiment:
|
|
//std::vector<int> nums = {100, 4, 200, 1, 3, 2};
|
|
//std::vector<int> nums = {0,3,7,2,5,8,4,6,0,1};
|
|
std::vector<int> nums = {100, 4, 200, 1, 3, 2, 2, 2, 2, 3};
|
|
|
|
int size = nums.size();
|
|
std::cout << "for vector {";
|
|
for(int i = 0; i < size; i++){
|
|
if(i < size - 1) std::cout << nums[i] << ",";
|
|
else std::cout << nums[i];
|
|
}
|
|
std::cout << "}\n";
|
|
|
|
int length = longestConsecutive(nums);
|
|
std::cout << "The length of the longest consecutive sequence is: "
|
|
<< length << std::endl;
|
|
return 0;
|
|
}
|