Unordered Map
#include <iostream>
#include <limits>
#include <unordered_map>
#include <vector>
/**
* @brief Demonstrates the use of std::unordered_map in C++.
*
* This program showcases the efficiency of unordered maps for tracking element occurrences
* and calculating maximum block sizes in a vector.
* It includes both a brute force and an optimized approach to solving the problem of
* minimizing the maximum block size after removing a specified integer from the vector.
*/
/**
* @brief Finds the integer that, when removed, minimizes the maximum length of contiguous blocks.
*
* This function iterates over the vector to calculate the size of blocks formed when removing
* each distinct integer and returns the integer that results in the smallest maximum block size.
*
* @param vec The vector of integers.
* @return The integer that minimizes the maximum block size when removed.
*/
int minimal_max_block(const std::vector<int> &vec) {
std::unordered_map<int, int> last_occurrence;
std::unordered_map<int, int> max_block_sizes;
// Traverse the vector
for (size_t i = 0; i < vec.size(); ++i) {
int num = vec[i];
// If it's the first occurrence, consider the block from the start to current position
if (last_occurrence.find(num) == last_occurrence.end()) {
max_block_sizes[num] = i; // Initial block size
} else {
// Calculate block size excluding the number itself
int block_size = i - last_occurrence[num] - 1;
max_block_sizes[num] = std::max(max_block_sizes[num], block_size);
}
// Update the last occurrence index
last_occurrence[num] = i;
}
// Handle tail blocks
for (const auto &entry : last_occurrence) {
int num = entry.first;
int pos = entry.second;
int block_size = vec.size() - pos - 1; // Tail block size
max_block_sizes[num] = std::max(max_block_sizes[num], block_size);
}
// Find the number with the smallest maximum block size
int min_num = -1;
int min_block_size = std::numeric_limits<int>::max();
for (const auto &entry : max_block_sizes) {
if (entry.second < min_block_size) {
min_block_size = entry.second;
min_num = entry.first;
}
}
return min_num;
}
/**
* @brief A brute force approach to find the integer that minimizes the maximum block size.
*
* This function examines every unique integer in the vector and calculates the maximum
* size of blocks formed by removing that integer.
*
* @param vec The vector of integers.
* @return The integer that minimizes the maximum block size when removed.
*/
int minimal_max_block_bruteforce(const std::vector<int> &vec) {
int min_max_block_size = std::numeric_limits<int>::max();
int min_num = -1;
std::unordered_map<int, int> unique_elements;
for (int num : vec) {
unique_elements[num]++;
}
for (const auto &entry : unique_elements) {
int num = entry.first;
std::vector<int> indices;
// Collect indices of the current number
for (size_t i = 0; i < vec.size(); ++i) {
if (vec[i] == num) {
indices.push_back(i);
}
}
indices.insert(indices.begin(), -1);
indices.push_back(vec.size());
int max_block_size = 0;
for (size_t i = 1; i < indices.size(); ++i) {
max_block_size = std::max(max_block_size, indices[i] - indices[i - 1] - 1);
}
if (max_block_size < min_max_block_size) {
min_max_block_size = max_block_size;
min_num = num;
}
}
return min_num;
}
int main() {
std::vector<int> vec = {1, 2, 2, 3, 1, 4, 4, 4, 1, 2, 5};
std::cout << "Brute Force Result: " << minimal_max_block_bruteforce(vec) << std::endl;
std::cout << "Optimized Result: " << minimal_max_block(vec) << std::endl;
return 0;
}