C++ Coding Interview Cheat Sheet — Complete STL & Syntax Guide
A practical, no-fluff guide to the C++ Standard Template Library (STL), syntax, and idioms you’ll reach for most during a technical interview.
Why C++ for Coding Interviews?
C++ remains a powerhouse in technical interviews, particularly at companies focusing on systems, performance, or trading. Here is why it shines:
- Unmatched Performance: C++ is bare-metal fast. If an interview problem has strict time limits, a well-written C++ solution will pass test cases that might time out in slower languages.
- The Standard Template Library (STL): The STL provides heavily optimized, rigorously tested implementations of almost every data structure and algorithm you will need, from
std::priority_queuetostd::lower_bound. - Absolute Control: You control the memory, the data layouts, and the references. This allows for in-place modifications and zero-copy tricks that aren’t possible in managed languages.
- Industry Standard: It is the lingua franca of competitive programming and systems engineering. Interviewers at FAANG companies are intimately familiar with C++ code.
If you're building your full preparation plan, start with our How to Prepare for a Coding Interview guide. This also pairs perfectly with Data Structures for Coding Interviews.
Looking for a different language? Python, Java, JavaScript, Go.
Already know why C++? Try a free C++ mock interview on Intervu →
1. Data Types & Variables
#include <bits/stdc++.h>
using namespace std;
// Integer types
int x = 10;
long long big = 1LL << 60; // safe large value — avoid 1e18 (double literal, lossy!)
unsigned int u = 42;
// Float / Double
double pi = 3.14159;
float f = 3.14f;
// Boolean
bool flag = true; // true / false (lowercase)
// Char
char c = 'A';
// Auto (type inference)
auto val = 42; // int
auto s = string("hello");
// Constants — use integer literals, not floating-point!
const int MAX = 1'000'000'000; // 10^9 — NOT 1e9 (that's a double!)
constexpr int MOD = 1'000'000'007;
// Infinity
int INF = INT_MAX; // 2^31 - 1
long long LINF = LLONG_MAX;
// Multiple assignment
int a = 1, b = 2, c = 3;
// Swap
swap(a, b); // O(1), built into STL
Key tip: Always use long long when values can exceed ~2×10⁹. Intermediate multiplication like a * b can silently overflow int — cast early: (long long)a * b.
2. Strings
Strings are central to C++ coding interviews — from palindrome checks to substring searches.
#include <string>
string s = "hello world";
// Basics
s.size() // 11 (also s.length())
s[0] // 'h'
s.back() // 'd' (last char)
s.front() // 'h' (first char)
s.substr(6, 5) // "world" (start, length)
s.substr(6) // "world" (to end)
// Modify
s += " again"; // append
s.push_back('!'); // append single char
s.pop_back(); // remove last char
s.insert(5, ", there"); // insert at position
s.erase(5, 6); // erase(start, length)
s.replace(0, 5, "bye"); // replace(start, length, new_str)
// Search
s.find("world") // 6 (string::npos if not found)
s.find('o') // first occurrence
s.rfind('o') // last occurrence
s.find("xyz") == string::npos // check not found
// Convert
stoi("123") // string → int
stoll("123") // string → long long
stod("3.14") // string → double
to_string(42) // int → string
// Char checks (from <cctype>)
isalpha(c) // is letter
isdigit(c) // is digit
isalnum(c) // is letter or digit
isupper(c) / islower(c)
toupper(c) / tolower(c)
// Char ↔ int
'a' - 'a' // 0
c - '0' // digit char to int value
// String stream (for parsing)
#include <sstream>
stringstream ss("1 2 3");
int a; ss >> a; // reads token by token
Key tip: string::npos is returned from find() on a miss — always check against it explicitly, not -1. They happen to be equal on most platforms, but relying on that is undefined behavior.
3. Arrays & Vectors
vector is the default container for most C++ coding interview problems. Know it inside out.
#include <vector>
// Raw array (fixed size)
int arr[5] = {1, 2, 3, 4, 5};
int arr2[10] = {}; // zero-initialized
// Vector (dynamic array — preferred)
vector<int> v = {3, 1, 4, 1, 5};
vector<int> zeros(10, 0); // 10 zeros
vector<int> empty;
// 2D vector
vector<vector<int>> mat(rows, vector<int>(cols, 0));
// Access
v[0] // 3
v.front() // first element
v.back() // last element
v.size() // number of elements
v.empty() // true if empty
// Modify
v.push_back(9); // append — amortized O(1)
v.pop_back(); // remove last — O(1)
v.insert(v.begin() + i, val); // insert at index — O(n)
v.erase(v.begin() + i); // remove at index — O(n)
v.erase(v.begin()+l, v.begin()+r); // remove range [l, r)
v.clear(); // remove all elements
v.resize(20); // resize (fills with 0)
v.assign(10, 5); // fill with 10 fives
// Slicing — copy a subrange
vector<int> sub(v.begin() + 1, v.begin() + 4);
// Reverse
reverse(v.begin(), v.end());
// Iteration
for (int x : v) { } // range-based for
for (int i = 0; i < v.size(); i++) { } // index-based
for (auto& x : v) { x *= 2; } // by reference
// Initialize with iota
vector<int> idx(n);
iota(idx.begin(), idx.end(), 0); // 0, 1, 2, ..., n-1
Key tip: v.size() returns an unsigned type. The expression v.size() - 1 >= 0 is always true (wraps to max value when 0). Use (int)v.size() when doing arithmetic comparisons.
4. Stack, Queue & Deque
#include <stack>
#include <queue>
#include <deque>
// Stack (LIFO)
stack<int> st;
st.push(1);
st.push(2);
st.top() // peek top — 2
st.pop(); // remove top (returns void!)
st.size();
st.empty();
// Queue (FIFO)
queue<int> q;
q.push(1);
q.push(2);
q.front() // peek front — 1
q.back() // peek back — 2
q.pop(); // remove front (returns void!)
// Deque (double-ended queue)
deque<int> dq;
dq.push_back(1); // add right
dq.push_front(0); // add left — O(1)
dq.pop_back(); // remove right
dq.pop_front(); // remove left — O(1)
dq.front();
dq.back();
dq[i]; // random access — O(1)
Key tip: stack::pop() and queue::pop() return void — always read .top() / .front() before calling .pop(), or you’ll lose the value.
5. Sets & Multisets
#include <set>
#include <unordered_set>
// set — ordered, unique, O(log n)
set<int> s = {3, 1, 4, 1, 5}; // {1, 3, 4, 5}
s.insert(2);
s.erase(3);
s.count(4) // 1 if present, 0 if not
s.find(4) // iterator (s.end() if missing)
s.size();
s.empty();
// Lower/upper bound
s.lower_bound(3) // first element >= 3
s.upper_bound(3) // first element > 3
*s.begin() // min element
*s.rbegin() // max element
// multiset — ordered, allows duplicates
multiset<int> ms;
ms.insert(3); ms.insert(3);
ms.count(3) // 2
ms.erase(ms.find(3)) // erase ONE occurrence
ms.erase(3) // erases ALL occurrences — be careful!
// unordered_set — O(1) average, no ordering
unordered_set<int> us;
us.insert(1);
us.count(1) // 1 if present
us.find(1) != us.end() // contains check
// Iterate set (sorted order)
for (int x : s) { }
// Reverse iteration
for (auto it = s.rbegin(); it != s.rend(); it++) { }
6. Maps & Unordered Maps
Maps are essential in C++ coding interviews — used for frequency counting, graph adjacency, memoization, and more.
#include <map>
#include <unordered_map>
// map — sorted by key, O(log n)
map<string, int> m;
m["alice"] = 10;
m["bob"] = 20;
m.count("alice") // 1 if exists, 0 if not
m.find("alice") // iterator (m.end() if missing)
m.erase("bob");
m.size();
m.empty();
// Iterate (sorted by key)
for (auto& [key, val] : m) { // C++17 structured bindings
cout << key << " " << val;
}
for (auto& p : m) { // older style
cout << p.first << " " << p.second;
}
// Lower/upper bound
m.lower_bound("bob") // first key >= "bob"
m.upper_bound("bob") // first key > "bob"
// unordered_map — O(1) average, no key ordering
unordered_map<string, int> um;
um["a"] = 1;
um.count("a") // 1 if key exists
// Frequency map pattern
unordered_map<int, int> freq;
for (int x : v) freq[x]++;
Key tip: Accessing a missing key with map[key] inserts a default-constructed value. Use .count() or .find() to check existence without accidentally inserting.
7. Priority Queue (Heap)
The priority queue is the go-to structure in C++ coding interviews for problems involving the k-th largest element, Dijkstra’s algorithm, or greedy scheduling.
#include <queue>
// Max-heap (default)
priority_queue<int> pq;
pq.push(3); pq.push(1); pq.push(4);
pq.top() // 4 (max)
pq.pop(); // removes max
pq.size();
pq.empty();
// Min-heap
priority_queue<int, vector<int>, greater<int>> minPQ;
minPQ.push(3); minPQ.push(1);
minPQ.top() // 1 (min)
// Custom comparator (min-heap by second element of pair)
auto cmp = [](pair<int,int>& a, pair<int,int>& b) {
return a.second > b.second;
};
priority_queue<pair<int,int>, vector<pair<int,int>>, decltype(cmp)> pq2(cmp);
// Heap of pairs — sorted by first element (max)
priority_queue<pair<int,int>> pairPQ;
pairPQ.push({5, 10});
pairPQ.push({3, 20});
pairPQ.top() // {5, 10}
// Build from vector
vector<int> data = {3, 1, 4, 1, 5};
priority_queue<int> fromVec(data.begin(), data.end());
8. Pairs & Tuples
#include <utility>
#include <tuple>
// Pair
pair<int, int> p = {1, 2};
p.first // 1
p.second // 2
make_pair(1, 2) // alternative constructor
// Pairs are comparable lexicographically
{1, 2} < {1, 3} // true
{2, 0} < {1, 9} // false
// Tuple
tuple<int, string, double> t = {1, "hi", 3.14};
get<0>(t) // 1
get<1>(t) // "hi"
// Structured bindings (C++17)
auto [x, y] = p;
auto [a, b, c] = t;
for (auto& [key, val] : myMap) { }
9. Control Flow
// if / else if / else
if (x > 0) { }
else if (x == 0) { }
else { }
// Ternary
int result = (x > 0) ? x : -x;
// for loop
for (int i = 0; i < n; i++) { }
for (int i = n - 1; i >= 0; i--) { }
for (int i = 0; i < n; i += 2) { }
// Range-based for (C++11)
for (int x : v) { }
for (auto& [k, v] : myMap) { }
// while / do-while
while (condition) { }
do { } while (condition);
// break / continue
for (int i = 0; i < n; i++) {
if (i == 5) break;
if (i % 2 == 0) continue;
}
10. Functions & Lambdas
// Basic function
int add(int a, int b) { return a + b; }
// Pass by reference (avoid copies, allow modification)
void doubleVal(int& x) { x *= 2; }
// Pass by const reference (avoid copy, read-only)
int sumVec(const vector<int>& v) {
return accumulate(v.begin(), v.end(), 0);
}
// Lambda
auto square = [](int x) { return x * x; };
// Capturing variables
int mult = 3;
auto triple = [mult](int x) { return x * mult; }; // by value
auto addTo = [&mult](int x) { mult += x; }; // by reference
auto captAll = [=](int x) { return x + mult; }; // capture all by value
// Lambda as comparator
sort(v.begin(), v.end(), [](int a, int b) {
return a > b; // descending
});
// Recursive lambda (C++14)
function<int(int)> fib = [&](int n) -> int {
if (n <= 1) return n;
return fib(n-1) + fib(n-2);
};
11. Sorting
#include <algorithm>
vector<int> v = {3, 1, 4, 1, 5};
// Sort ascending
sort(v.begin(), v.end());
// Sort descending
sort(v.begin(), v.end(), greater<int>());
// Custom comparator
sort(v.begin(), v.end(), [](int a, int b) {
return a > b;
});
// Sort by second element of pair
vector<pair<int,int>> pairs = {{1,3},{2,1},{3,2}};
sort(pairs.begin(), pairs.end(), [](auto& a, auto& b) {
return a.second < b.second;
});
// Sort by multiple criteria
sort(data.begin(), data.end(), [](auto& a, auto& b) {
if (a.first != b.first) return a.first < b.first;
return a.second > b.second; // tie-break descending
});
// Partial sort (only sort first k)
partial_sort(v.begin(), v.begin() + k, v.end());
// nth_element — O(n) average — makes v[k] the correct element
nth_element(v.begin(), v.begin() + k, v.end());
// Stable sort
stable_sort(v.begin(), v.end());
12. Binary Search
#include <algorithm>
vector<int> v = {1, 3, 5, 7, 9}; // must be sorted
// Check existence
binary_search(v.begin(), v.end(), 5) // true/false
// lower_bound — first element >= val
auto it = lower_bound(v.begin(), v.end(), 5);
int idx = it - v.begin(); // convert to index
// upper_bound — first element > val
auto it2 = upper_bound(v.begin(), v.end(), 5);
// Count occurrences
int cnt = upper_bound(v.begin(), v.end(), 5)
- lower_bound(v.begin(), v.end(), 5);
// Floor: largest element <= val
auto it3 = upper_bound(v.begin(), v.end(), val);
if (it3 != v.begin()) { --it3; /* *it3 is floor */ }
// Manual binary search template
int lo = 0, hi = n - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2; // avoids overflow
if (v[mid] == target) return mid;
else if (v[mid] < target) lo = mid + 1;
else hi = mid - 1;
}
// Binary search on answer (monotonic predicate)
lo = 0; hi = 1e9;
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
if (feasible(mid)) hi = mid;
else lo = mid + 1;
}
// lo is the answer
13. STL Algorithms
#include <algorithm>
#include <numeric>
vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};
// Min / Max
*min_element(v.begin(), v.end())
*max_element(v.begin(), v.end())
min(a, b); max(a, b);
min({a, b, c}); max({a, b, c}); // initializer list (C++11)
// Sum
accumulate(v.begin(), v.end(), 0)
accumulate(v.begin(), v.end(), 1LL, multiplies<long long>()) // product
// Count
count(v.begin(), v.end(), 1)
count_if(v.begin(), v.end(), [](int x) { return x > 3; })
// Find
find(v.begin(), v.end(), 4)
find_if(v.begin(), v.end(), [](int x) { return x > 5; })
// Fill
fill(v.begin(), v.end(), 0);
fill_n(v.begin(), 5, -1);
// Transform
transform(v.begin(), v.end(), v.begin(), [](int x) { return x * 2; });
// Remove consecutive duplicates (sort first!)
sort(v.begin(), v.end());
auto last = unique(v.begin(), v.end());
v.erase(last, v.end());
// Rotate left by k
rotate(v.begin(), v.begin() + k, v.end());
// Permutations
next_permutation(v.begin(), v.end());
prev_permutation(v.begin(), v.end());
// Prefix sum
vector<int> prefix(v.size() + 1, 0);
partial_sum(v.begin(), v.end(), prefix.begin() + 1);
// Iota — fill with incrementing values
vector<int> idx(n);
iota(idx.begin(), idx.end(), 0); // 0, 1, 2, ..., n-1
// GCD / LCM (C++17)
gcd(12, 8); // 4
lcm(4, 6); // 12
14. Bit Manipulation
Bit manipulation problems appear regularly in C++ coding interviews. These are the tricks worth memorizing.
// Bitwise operators
x & y // AND
x | y // OR
x ^ y // XOR
~x // NOT
x << k // left shift (= x * 2^k)
x >> k // right shift (= x / 2^k)
// Common tricks
x & 1 // check if odd
x & (x - 1) // clear lowest set bit
x & (-x) // isolate lowest set bit
x ^ x // 0
x ^ 0 // x
// Power of 2 check
bool isPow2 = (x > 0) && (x & (x - 1)) == 0;
// Count set bits
__builtin_popcount(x) // int
__builtin_popcountll(x) // long long
// Count leading / trailing zeros
// ⚠️ __builtin_clz(0) and __builtin_ctz(0) are undefined behavior!
__builtin_clz(x) __builtin_clzll(x) // only valid when x != 0
__builtin_ctz(x) __builtin_ctzll(x) // only valid when x != 0
// Set / clear / toggle / read bit k
x |= (1 << k) // set bit k
x &= ~(1 << k) // clear bit k
x ^= (1 << k) // toggle bit k
(x >> k) & 1 // read bit k
// Iterate over all subsets of n elements
for (int mask = 0; mask < (1 << n); mask++) {
for (int i = 0; i < n; i++) {
if (mask & (1 << i)) {
// element i is in this subset
}
}
}
15. Math & Numbers
#include <cmath>
#include <numeric>
pow(2.0, 10) // 1024.0
sqrt(16.0) // 4.0
abs(-5) // 5 (int)
fabs(-3.14) // 3.14 (double)
floor(3.7) // 3.0
ceil(3.2) // 4.0
round(3.5) // 4.0
log2(8) // 3.0
log10(100) // 2.0
// Modular arithmetic
(a % MOD + MOD) % MOD // always-positive mod
(long long)a * b % MOD // avoid overflow before mod
// Fast modular exponentiation (manual)
long long powmod(long long base, long long exp, long long mod) {
long long result = 1;
base %= mod;
while (exp > 0) {
if (exp & 1) result = result * base % mod;
base = base * base % mod;
exp >>= 1;
}
return result;
}
// GCD / LCM
__gcd(a, b) // always available
gcd(a, b) // C++17 <numeric>
lcm(a, b) // C++17 <numeric>
// Integer limits
INT_MAX // ~2.1 × 10^9
INT_MIN
LLONG_MAX // ~9.2 × 10^18
LLONG_MIN
16. Common Algorithm Patterns
These are the patterns behind the majority of C++ coding interview questions. Learn the templates, then practice applying them under time pressure.
Two Pointers
bool twoSumSorted(vector<int>& arr, int target) {
int l = 0, r = arr.size() - 1;
while (l < r) {
int sum = arr[l] + arr[r];
if (sum == target) return true;
else if (sum < target) l++;
else r--;
}
return false;
}
Sliding Window
int maxSumSubarray(vector<int>& arr, int k) {
int window = 0;
for (int i = 0; i < k; i++) window += arr[i];
int best = window;
for (int i = k; i < (int)arr.size(); i++) {
window += arr[i] - arr[i - k];
best = max(best, window);
}
return best;
}
Fast & Slow Pointers
bool hasCycle(ListNode* head) {
ListNode* slow = head, *fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) return true;
}
return false;
}
BFS Template
void bfs(vector<vector<int>>& graph, int start) {
vector<bool> visited(graph.size(), false);
queue<int> q;
q.push(start);
visited[start] = true;
while (!q.empty()) {
int node = q.front(); q.pop();
for (int neighbor : graph[node]) {
if (!visited[neighbor]) {
visited[neighbor] = true;
q.push(neighbor);
}
}
}
}
DFS Template (Recursive)
void dfs(vector<vector<int>>& graph, int node, vector<bool>& visited) {
visited[node] = true;
for (int neighbor : graph[node]) {
if (!visited[neighbor])
dfs(graph, neighbor, visited);
}
}
Binary Search on Answer
int lo = 0, hi = 1e9;
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
if (feasible(mid)) hi = mid;
else lo = mid + 1;
}
// lo is the minimum feasible value
Dynamic Programming — Memoization
unordered_map<int, long long> memo;
long long dp(int n) {
if (n <= 1) return n;
if (memo.count(n)) return memo[n];
return memo[n] = dp(n-1) + dp(n-2);
}
// Or with a fixed array + recursive lambda
vector<long long> cache(n + 1, -1);
function<long long(int)> solve = [&](int i) -> long long {
if (i <= 1) return i;
if (cache[i] != -1) return cache[i];
return cache[i] = solve(i-1) + solve(i-2);
};
Prefix Sum
vector<int> arr = {1, 2, 3, 4, 5};
vector<int> prefix(arr.size() + 1, 0);
for (int i = 0; i < (int)arr.size(); i++)
prefix[i + 1] = prefix[i] + arr[i];
// Range sum query [l, r] inclusive:
int rangeSum = prefix[r + 1] - prefix[l];
Monotonic Stack
vector<int> nextGreater(vector<int>& arr) {
int n = arr.size();
vector<int> result(n, -1);
stack<int> st; // stores indices
for (int i = 0; i < n; i++) {
while (!st.empty() && arr[i] > arr[st.top()]) {
result[st.top()] = arr[i];
st.pop();
}
st.push(i);
}
return result;
}
Union-Find (Disjoint Set Union)
struct UnionFind {
vector<int> parent, rank;
UnionFind(int n) : parent(n), rank(n, 0) {
iota(parent.begin(), parent.end(), 0);
}
int find(int x) {
if (parent[x] != x)
parent[x] = find(parent[x]); // path compression
return parent[x];
}
bool unite(int x, int y) {
int px = find(x), py = find(y);
if (px == py) return false;
if (rank[px] < rank[py]) swap(px, py);
parent[py] = px;
if (rank[px] == rank[py]) rank[px]++;
return true;
}
bool connected(int x, int y) { return find(x) == find(y); }
};
Standard Struct Definitions
Many LeetCode C++ problems reference these — write them from memory when not pre-provided:
// Singly linked list node
struct ListNode {
int val;
ListNode* next;
ListNode(int val) : val(val), next(nullptr) {}
ListNode(int val, ListNode* next) : val(val), next(next) {}
};
// Binary tree node
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int val) : val(val), left(nullptr), right(nullptr) {}
};
Building a Graph from an Edge List
BFS/DFS templates assume graph[node] — here’s how to construct it:
int n; // number of nodes
vector<vector<int>> graph(n);
// Undirected
for (auto& e : edges) {
graph[e[0]].push_back(e[1]);
graph[e[1]].push_back(e[0]);
}
// Weighted (store {neighbor, weight})
vector<vector<pair<int,int>>> wgraph(n);
for (auto& e : edges) {
wgraph[e[0]].push_back({e[1], e[2]});
wgraph[e[1]].push_back({e[0], e[2]});
}
DFS Template (Iterative)
void dfsIterative(vector<vector<int>>& graph, int start) {
vector<bool> visited(graph.size(), false);
stack<int> st;
st.push(start);
while (!st.empty()) {
int node = st.top(); st.pop();
if (visited[node]) continue;
visited[node] = true;
for (int neighbor : graph[node])
if (!visited[neighbor])
st.push(neighbor);
}
}
Backtracking Template
Use for subsets, permutations, combinations, N-Queens, and word search:
vector<vector<int>> result;
void backtrack(vector<int>& nums, int start, vector<int>& path) {
result.push_back(path); // auto-copies in C++ — no snapshot boilerplate needed
for (int i = start; i < (int)nums.size(); i++) {
path.push_back(nums[i]); // choose
backtrack(nums, i + 1, path); // explore
path.pop_back(); // undo (backtrack)
}
}
// Call: backtrack(nums, 0, path);
Key tip: Unlike Java, result.push_back(path) in C++ copies the vector automatically, so you never need new ArrayList<>(path)-style boilerplate.
Trie (Prefix Tree)
Used for word search, autocomplete, and prefix-matching problems:
struct TrieNode {
unordered_map<char, TrieNode*> children;
bool isEnd = false;
};
struct Trie {
TrieNode* root = new TrieNode();
void insert(const string& word) {
TrieNode* node = root;
for (char c : word) {
if (!node->children.count(c))
node->children[c] = new TrieNode();
node = node->children[c];
}
node->isEnd = true;
}
bool search(const string& word) {
TrieNode* node = root;
for (char c : word) {
if (!node->children.count(c)) return false;
node = node->children[c];
}
return node->isEnd;
}
bool startsWith(const string& prefix) {
TrieNode* node = root;
for (char c : prefix) {
if (!node->children.count(c)) return false;
node = node->children[c];
}
return true;
}
};
Fast I/O Setup
// Add at the top of main() — essential for competitive-style problems
ios_base::sync_with_stdio(false);
cin.tie(NULL);
// Read line
string line;
getline(cin, line);
// Read until EOF
int x;
while (cin >> x) { }
Quick Reference Cheat Sheet
| Task | Snippet |
|---|---|
| Max/min of values | max(a, b) / min({a,b,c}) |
| Sort ascending | sort(v.begin(), v.end()) |
| Sort descending | sort(v.begin(), v.end(), greater<int>()) |
| Reverse vector | reverse(v.begin(), v.end()) |
| Binary search | lower_bound(v.begin(), v.end(), val) |
| Set floor (largest<=val) | auto it = s.upper_bound(val); if (it != s.begin()) --it; |
| Sum of vector | accumulate(v.begin(), v.end(), 0) |
| Count occurrences | count(v.begin(), v.end(), val) |
| Remove duplicates | sort + unique + erase |
| Frequency map | unordered_map<int,int> freq; freq[x]++ |
| Min-heap | priority_queue<int, vector<int>, greater<int>> |
| Check bit k | (x >> k) & 1 |
| Count set bits | __builtin_popcount(x) |
| Infinity | INT_MAX / LLONG_MAX |
| Long long literal | 1LL << 40 or (long long)a * b |
| Fast I/O | ios_base::sync_with_stdio(false); cin.tie(NULL) |
| Build graph | vector<vector<int>> graph(n); + iterate edges |
| Backtrack snapshot | result.push_back(path) (auto-copies in C++) |
Related Interview Topics
Solid on C++ syntax? The next step is mastering how these tools map to the core problem categories you’ll face in interviews:
- Arrays & Hashing —
unordered_mapfrequency maps, two-sum variants - Binary Search —
lower_bound/upper_bound, binary search on answer - Trees & Graphs — BFS/DFS with
queue/stack, Dijkstra withpriority_queue - Dynamic Programming — memoization with
unordered_map, tabulation withvector - Intervals & Greedy — sorting with custom comparators,
multisetfor active intervals
Each of these patterns has dedicated walkthroughs on the Intervu blog.
Practice Under Real Interview Conditions
Knowing the C++ STL is necessary — but not sufficient. In a live coding interview, you need to recall and apply these patterns quickly, explain your reasoning out loud, and handle follow-up questions on the fly.
The gap between “I know this” and “I can do this under pressure” is closed through deliberate practice. Intervu simulates exactly that: timed mock interviews with an AI interviewer that asks follow-ups, gives feedback on your reasoning, and helps you identify the patterns you actually struggle with — not just the ones you think you do.
Ready to test yourself? Start a free mock interview on Intervu →