What is the STL and what are its main components?
The generic part of the standard library: containers (
vector,map,unordered_map...), container adaptors (stack,queue,priority_queue), iterators, algorithms (sort,find,accumulate) and function objects such as lambdas. Algorithms work on iterator ranges, not on containers.C++#include <algorithm> #include <iostream> #include <vector> using namespace std; int main() { vector<int> v = {5, 2, 9, 1}; sort(v.begin(), v.end()); auto it = find(v.begin(), v.end(), 9); cout << "sorted: "; for (int x : v) cout << x << " "; cout << "| 9 at index " << (it - v.begin()) << "\n"; }This prints
sorted: 1 2 5 9 | 9 at index 3.What is the difference between
vector,listanddeque?vectordequelistRandom access O(1) O(1) no Insert at front O(n) O(1) O(1) Insert in middle O(n) O(n) O(1) with an iterator All three add at the end in amortized O(1). Default to
vector: one contiguous block beatslisteven for many middle insertions, because walking a list costs a cache miss per node. Usedequefor both ends andlistfor stable iterators.What is the difference between
mapandunordered_mapin C++?std::mapkeeps sorted keys in a balanced binary search tree (red-black in the major libraries) with O(log n) operations.std::unordered_mapis a hash table with no order, O(1) on average and O(n) in the worst case.Use
unordered_mapfor plain lookups andmapfor sorted output orlower_boundqueries. The hash table visualization shows buckets and collisions.Practice it: Two Sum, Group Anagrams
In what order does a
std::mapiterate its keys?C++#include <iostream> #include <map> #include <string> using namespace std; int main() { map<string, int> m; m["pear"] = 3; m["apple"] = 5; m["fig"] = 1; m["apple"] += 1; for (auto& [k, v] : m) cout << k << "=" << v << " "; cout << "\n"; }It prints
apple=6 fig=1 pear=3.std::mapkeeps its keys sorted, so iteration is alphabetical whatever the insertion order, andm["apple"] += 1adds to the existing value. Withstd::unordered_mapthe order would be unspecified.What happens when you read a missing key with
map[key]?C++#include <iostream> #include <map> #include <string> using namespace std; int main() { map<string, int> m; if (m["missing"] == 0) cout << "zero "; cout << m.size() << "\n"; }It prints
zero 1.operator[]inserts a value-initialized element when the key is missing, so readingm["missing"]adds the key with value 0.To look up without inserting, use
m.find(key),m.count(key),m.at(key)(throws if missing) or C++20'sm.contains(key).How does
std::vectorgrow? What is the difference between size and capacity?size()is how many elements the vector holds;capacity()is how many fit before it must reallocate. When full, it allocates a block a constant factor larger and moves the elements, sopush_backis amortized O(1).C++#include <iostream> #include <vector> int main() { std::vector<int> v; size_t last = 0; for (int i = 0; i < 20; ++i) { v.push_back(i); if (v.capacity() != last) { last = v.capacity(); std::cout << last << " "; } } std::cout << "\n"; }With GCC's libstdc++ this prints
1 2 4 8 16 32; MSVC grows by 1.5 times. Reallocation invalidates every pointer and iterator. See the vector docs.What is iterator invalidation? How do you erase from a container while iterating?
When a container change leaves an iterator pointing at freed or moved memory; using it is undefined behavior. A
vectorreallocation invalidates all iterators; inlist,mapandsetonly the erased element's. To erase while iterating, continue from the iteratorerasereturns.C++#include <iostream> #include <vector> using namespace std; int main() { vector<int> v = {1, 2, 3, 4, 5, 6}; for (auto it = v.begin(); it != v.end(); ) { if (*it % 2 == 0) it = v.erase(it); else ++it; } for (int x : v) cout << x << " "; cout << "\n"; }This prints
1 3 5. More in the iterators docs.Does
std::removechange a vector's size?C++#include <algorithm> #include <iostream> #include <vector> using namespace std; int main() { vector<int> v = {1, 2, 3, 2, 4, 2}; auto newEnd = remove(v.begin(), v.end(), 2); cout << v.size() << " "; v.erase(newEnd, v.end()); cout << v.size() << "\n"; }It prints
6 3.std::removeonly sees iterators, so it cannot change the size: it shifts the kept elements (1, 3, 4) to the front and returns the new logical end.erasethen cuts the leftover tail.Together that is the erase-remove idiom,
v.erase(remove(v.begin(), v.end(), 2), v.end());. C++20'sstd::erase(v, 2)andstd::erase_ifdo both steps.Practice it: Remove Duplicates from Sorted Array, Move Zeroes
Is
std::priority_queuea min-heap or a max-heap by default?C++#include <functional> #include <iostream> #include <queue> #include <vector> using namespace std; int main() { priority_queue<int> maxq; priority_queue<int, vector<int>, greater<int>> minq; for (int x : {4, 1, 7, 3}) { maxq.push(x); minq.push(x); } cout << maxq.top() << " " << minq.top() << "\n"; }It prints
7 1.std::priority_queueis a max-heap by default. For a min-heap passstd::greater<int>as the third template argument, which means also naming the container,vector<int>, as the second.pushandpopare O(log n) andtopis O(1). The heap visualization shows a min-heap sifting each value up.Practice it: Kth Largest Element in an Array, Last Stone Weight, Top K Frequent Elements
Which algorithm does
std::sortuse, and how do you sort with a custom comparator?Introsort in GCC's libstdc++ and MSVC (quicksort falling back to heapsort, insertion sort for small ranges), with O(n log n) guaranteed since C++11. It is not stable; use
std::stable_sortfor that.C++#include <algorithm> #include <iostream> #include <vector> using namespace std; int main() { vector<pair<int, int>> intervals = {{5, 7}, {1, 3}, {2, 4}, {1, 2}}; sort(intervals.begin(), intervals.end(), [](const auto& a, const auto& b) { if (a.first != b.first) return a.first < b.first; return a.second < b.second; }); for (auto& [s, e] : intervals) cout << "[" << s << "," << e << "] "; cout << "\n"; }This prints
[1,2] [1,3] [2,4] [5,7]. The comparator must be a strict weak ordering, so<=is undefined behavior. The quicksort visualization shows the partition step.Practice it: Merge Intervals, Non-overlapping Intervals
What is the difference between
push_backandemplace_back?push_backcopies or moves an existing object into the vector.emplace_backtakes constructor arguments and builds the element in place.C++#include <iostream> #include <vector> using namespace std; struct P { P(int, int) { cout << "ctor "; } P(const P&) { cout << "copy "; } P(P&&) noexcept { cout << "move "; } }; int main() { vector<P> v; v.reserve(2); v.push_back(P(1, 2)); v.emplace_back(3, 4); cout << "\n"; }This prints
ctor move ctor. The trap:emplace_backcallsexplicitconstructors, sov.emplace_back(10)on avector<vector<int>>adds a vector of ten zeros wherepush_back(10)would not compile.What does a
std::setbuilt from a vector with duplicates hold?C++#include <iostream> #include <set> #include <vector> using namespace std; int main() { vector<int> v = {3, 1, 3, 2, 1}; set<int> s(v.begin(), v.end()); cout << s.size() << " " << *s.begin() << " " << *s.rbegin() << "\n"; }It prints
3 1 3. Astd::setkeeps one copy of each value and stays sorted, so it holds{1, 2, 3},*s.begin()is 1 and*s.rbegin()is 3.When order does not matter,
std::unordered_setgives O(1) average lookups instead of O(log n).Practice it: Contains Duplicate
What are
std::stackandstd::queue, and what are container adaptors?std::stack(last in, first out) andstd::queue(first in, first out) are container adaptors: they wrap another container,std::dequeby default, and expose onlypush,pop,toporfront,emptyandsize. They cannot be iterated, andpop()returnsvoid, so readtop()first.C++#include <iostream> #include <stack> #include <string> using namespace std; bool balanced(const string& s) { stack<char> st; for (char c : s) { if (c == '(' || c == '[' || c == '{') { st.push(c); continue; } if (st.empty()) return false; char open = st.top(); st.pop(); if ((c == ')' && open != '(') || (c == ']' && open != '[') || (c == '}' && open != '{')) return false; } return st.empty(); } int main() { cout << balanced("{[()]}") << " " << balanced("([)]") << "\n"; }This prints
1 0.Practice it: Valid Parentheses, Min Stack, Implement Queue Using Stacks
C++ STL Interview Questions
Which container to pick, what each operation costs, and the traps in map, vector and remove.