Core Concepts
Anagram Validation
Validating if two strings are anagrams can be efficiently solved using frequency counting:
class AnagramChecker {
public:
bool validateAnagram(string str1, string str2) {
int frequency[26] = {0};
for (char c : str1) {
frequency[c - 'a']++;
}
for (char c : str2) {
frequency[c - 'a']--;
}
for (int count : frequency) {
if (count != 0) return false;
}
return true;
}
};
This approach uses a fixed-size array to track character frequencies. By subtracting 'a' from each character, we map letters to array indices (0-25). The solution increments for the first string and decrements for the second, then checks if all counts are zero.
Set Container Fundamentals
Set containers store unique elements in sorted order. Unordered sets use hash tables for faster access without ordering.
#include <unordered_set>
#include <set>
// Container declarations
unordered_set<int> hashSet;
set<int> sortedSet;
multiset<int> duplicateSet;
// Basic operations
hashSet.insert(5);
hashSet.erase(3);
// Element lookup
if (hashSet.find(element) != hashSet.end()) {
// Element found
}
Array Intersection Using Sets
class IntersectionFinder {
public:
vector<int> findCommonElements(vector<int>& arr1, vector<int>& arr2) {
unordered_set<int> elementSet(arr1.begin(), arr1.end());
vector<int> commonElements;
for (int num : arr2) {
if (elementSet.erase(num)) {
commonElements.push_back(num);
}
}
return commonElements;
}
};
The erase method returns the number of elements removed, making it useful for checking existence while removing.
Iterator and Auto Keyword
Iterators provide pointer-like access to container elements:
vector<int> numbers = {1, 2, 3, 4, 5};
// Traditional iterator
for (vector<int>::iterator it = numbers.begin();
it != numbers.end(); ++it) {
cout << *it << " ";
}
// Modern auto syntax
for (auto it = numbers.begin(); it != numbers.end(); ++it) {
cout << *it << " ";
}
The auto keyword automatically deduces variable types, rqeuiring initialization at declaration.
Happy Number Detection
class HappyNumberDetector {
public:
int calculateDigitSquareSum(int num) {
int total = 0;
while (num > 0) {
int digit = num % 10;
total += digit * digit;
num /= 10;
}
return total;
}
bool isNumberHappy(int num) {
unordered_set<int> seenNumbers;
while (true) {
if (num == 1) return true;
if (seenNumbers.count(num)) return false;
seenNumbers.insert(num);
num = calculateDigitSquareSum(num);
}
}
};
This detects cycles by storing previously seen numbers. The digit extraction process uses modulus and division operations.
Map Container Operations
Maps store key-value pairs with efficient lookup:
#include <unordered_map>
#include <map>
// Map declarations
unordered_map<string, int> scoreMap;
map<string, int> orderedMap;
// Insertion methods
scoreMap.insert({"math", 95});
scoreMap["science"] = 88;
// Lookup and iteration
if (scoreMap.find("math") != scoreMap.end()) {
// Key exists
}
for (const auto& entry : scoreMap) {
cout << entry.first << ": " << entry.second << endl;
}
Two Sum Problem Solution
class PairSumFinder {
public:
vector<int> findTargetPair(vector<int>& numbers, int target) {
unordered_map<int, int> valueIndexMap;
for (int i = 0; i < numbers.size(); i++) {
int complement = target - numbers[i];
if (valueIndexMap.find(complement) != valueIndexMap.end()) {
return {i, valueIndexMap[complement]};
}
valueIndexMap[numbers[i]] = i;
}
return {};
}
};
This approach stores numbers and their indices while searching for complements. Insertion happens after checking to avoid self-matching.