vector, map & the STL
The Standard Template Library gives you fast, type-safe containers so you rarely need raw arrays or manual memory. These are the workhorses of competitive programming and interviews.
vector — the Default Container
std::vector is a resizable array that manages its own memory. It's the container you reach for by default — contiguous storage, O(1) random access, and amortized O(1) append.
#include <vector> #include <algorithm> std::vector<int> nums = {5, 2, 8, 1}; nums.push_back(9); // append — [5,2,8,1,9] nums.pop_back(); // remove last nums[0]; // 5 — no bounds check nums.at(0); // 5 — throws if out of range nums.size(); // 4 // sort with the STL algorithm std::sort(nums.begin(), nums.end()); // [1,2,5,8] // iterate without copying for (const auto& n : nums) std::cout << n; // reserve capacity up front to avoid reallocations nums.reserve(1000);
vec[i] does no bounds checking — an out-of-range index is undefined behavior (often a silent memory bug). Use vec.at(i) when you want a thrown exception instead.string
std::string is a managed, resizable character sequence — a huge upgrade over C's raw char*. It owns its memory and handles growth for you.
#include <string> std::string s = "Hello"; s += ", world"; // concatenation, resizes automatically s.length(); // 12 s.substr(0, 5); // "Hello" s.find("world"); // 7 (index), or std::string::npos if absent s[0]; // 'H' // build strings efficiently in a loop with += (no per-step copy) std::string out; for (int i = 0; i < 3; i++) out += std::to_string(i); // "012"
map & unordered_map
std::map keeps keys sorted (O(log n), a red-black tree). std::unordered_map is a hash table with O(1) average lookup but no ordering. Pick unordered when you don't need sorted keys.
#include <map> #include <unordered_map> std::unordered_map<std::string, int> scores; scores["alice"] = 95; // insert or update scores["bob"] = 88; scores["alice"]; // 95 scores.count("bob"); // 1 — key exists // count word frequency — the classic idiom std::unordered_map<std::string, int> freq; for (const auto& w : words) freq[w]++; // [] default-constructs to 0 // iterate key/value (structured bindings, C++17) for (const auto& [name, score] : scores) std::cout << name << ": " << score << "\n";
map[missingKey] inserts a default-constructed value (0 for int) rather than failing. Use .count(key) or .find(key) if you only want to check existence without inserting.set & pair
std::set stores unique, sorted values. std::pair and std::tuple bundle a fixed group of values together — handy for returning two things from a function.
#include <set> #include <utility> std::set<int> unique = {3, 1, 1, 2, 3}; // {1, 2, 3} — sorted, deduped unique.insert(5); unique.count(2); // 1 — present // pair — bundle two values std::pair<std::string, int> p = {"age", 30}; p.first; // "age" p.second; // 30 // return two values from a function std::pair<int, int> minmax(std::vector<int>& v) { return {*std::min_element(v.begin(), v.end()), *std::max_element(v.begin(), v.end())}; }