0% found this document useful (0 votes)
6 views11 pages

CPP STL Complete Interview Notes

The document provides comprehensive interview notes on C++ STL (Standard Template Library), covering essential components such as containers (Vector, List, Deque, Pair, Stack, Queue, Priority Queue, Map), algorithms, and iterators. It emphasizes the importance of STL for efficient coding during interviews, highlighting key features, functions, and time complexities of various containers. Additionally, it includes comparisons between different data structures and practical coding examples for better understanding.

Uploaded by

A Arathi
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views11 pages

CPP STL Complete Interview Notes

The document provides comprehensive interview notes on C++ STL (Standard Template Library), covering essential components such as containers (Vector, List, Deque, Pair, Stack, Queue, Priority Queue, Map), algorithms, and iterators. It emphasizes the importance of STL for efficient coding during interviews, highlighting key features, functions, and time complexities of various containers. Additionally, it includes comparisons between different data structures and practical coding examples for better understanding.

Uploaded by

A Arathi
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

C++ STL Complete Interview Notes

C++ STL (Standard Template Library) — Complete Interview Notes


0. Why STL?
1. Vector — Dynamic Array
2. List — Doubly Linked List
3. Deque — Double Ended Queue
4. Pair — (from <utility> , part of STL utility library)
5. Stack — LIFO (Last In First Out)
6. Queue — FIFO (First In First Out)
7. Priority Queue
8. Map — Key-Value Pairs
9. Set — Unique, Sorted Values
10. Algorithms
11. Iterators & Functors — Quick Recap
12. Time Complexity Cheat Sheet ⭐ (High-yield interview table)
13. Quick-Fire Interview Definitions
14. Interview Focus Areas Flagged for Your Prep
C++ STL (Standard Template Library) — Complete Interview Notes

From Zero to Advanced | Containers + Algorithms + Iterators + Code + Interview Angle

0. Why STL?

STL gives ready-made, well-tested containers and algorithms so you don’t have to implement data structures (sorting, queues,
stacks, etc.) from scratch during coding tests/interviews — saving huge amounts of time.

Example: Instead of writing merge sort/quick sort from scratch, just call sort() . Instead of implementing a queue for BFS, use
STL’s queue .

STL has 4 main parts: 1. Containers (most important for DSA — main focus of these notes) 2. Algorithms (2nd most
important) 3. Iterators 4. Functors (function objects, used with containers/algorithms)

1. Vector — Dynamic Array

Why not just use arrays?

C++ arrays have a fixed/constant size — cannot grow or shrink at runtime.


Vector = a dynamic, resizable array — can grow/shrink during runtime.

#include <vector>
vector<int> v; // empty vector, size = 0
cout << [Link](); // 0

How a vector grows internally (important interview concept)

Vector has two properties: size (number of elements currently stored) and capacity (how many elements it can currently
hold before needing to resize).
When a vector is full and a new element is pushed, a new vector of double the capacity is created internally, the old
data is copied over, and then the new element is inserted.
This doubling strategy is why push_back has amortized O(1) time complexity.

vector<int> v;
v.push_back(1); // size=1, capacity=1
v.push_back(2); // size=2, capacity=2
v.push_back(3); // size=3, capacity=4 (doubled from 2)
cout << [Link](); // 3
cout << [Link](); // 4

Core Vector Functions


Function Purpose

push_back(x) Insert x at the end

Similar to push_back but constructs the object in-place (avoids


emplace_back(x)
an extra copy) — matters more with complex objects like pair

pop_back() Removes the last element

Access element at index i (square-bracket notation preferred in


v[i] or [Link](i)
practice)

front() Returns first element

back() Returns last element

size() Number of elements

capacity() Current allocated capacity

clear() Removes all elements (size → 0, capacity unchanged)

empty() Returns true / false whether vector is empty

erase() Removes element(s) — costly, O(n) worst case

insert() Inserts element(s) at a given position — costly, O(n) worst case

vector<int> v = {1, 2, 3, 4, 5}; // initializer-list style


vector<int> v2(3, 10); // size 3, every element = 10 → {10,10,10}
vector<int> v3(v); // v3 initialized as a copy of v

for (int val : v) cout << val << " "; // range-based for loop

// front/back
cout << [Link](); // 1
cout << [Link](); // 5

Interview trap: push_back vs emplace_back — push_back expects the object already constructed in the required type;
emplace_back constructs the object in place, avoiding an unnecessary copy — most noticeable with types like pair .

erase() and insert() — using iterators

vector<int> v = {1, 2, 3, 4, 5};

[Link]([Link]()); // removes index 0 → {2,3,4,5}


[Link]([Link]() + 2); // removes index 2

// erase a RANGE — [start, end) — end is NOT included


[Link]([Link]() + 1, [Link]() + 3); // removes indices 1 and 2

[Link]([Link]() + 2, 100); // inserts 100 at index 2, shifts rest right


[Link](); // removes everything, size=0, capacity unchanged
cout << [Link](); // 1 (true) if empty

Interview fact: erase / insert are O(n) (costly) because elements need to shift; push_back / pop_back are O(1) (cheap).

Vector Iterators

[Link]() → points to index 0.


[Link]() → does NOT point to the last element (common misconception!). It points to the memory location just after
the last element (garbage/undefined value if dereferenced).
[Link]() → reverse begin, points to the last element.
[Link]() → reverse end, points to the position just before the first element.
vector<int> v = {1, 2, 3, 4, 5};

vector<int>::iterator it = [Link]();
for (it = [Link](); it != [Link](); it++) {
cout << *it << " "; // dereference iterator with *
}

// Reverse traversal
for (auto it = [Link](); it != [Link](); it++) {
cout << *it << " ";
}

// Modern C++ shortcut using `auto` (avoids writing the long iterator type)
for (auto it = [Link](); it != [Link](); it++) cout << *it << " ";

Interview one-liner: “ [Link]() points one-past-the-last-element, not to the last element itself — dereferencing it gives
undefined/garbage data.”

2. List — Doubly Linked List

list is a sequential container like vector, but internally implemented as a doubly linked list.
Supports insertion/removal from both ends: push_back , push_front , pop_back , pop_front , emplace_back ,
emplace_front .

#include <list>
list<int> l;
l.push_back(1); // {1}
l.push_back(2); // {1, 2}
l.push_front(3); // {3, 1, 2}
l.push_front(5); // {5, 3, 1, 2}

for (int val : l) cout << val << " "; // 5 3 1 2

l.pop_back(); // removes 2 → {5, 3, 1}


l.pop_front(); // removes 5 → {3, 1}

Most functions ( size , erase , clear , begin , rbegin , rend , insert , front , back ) work the same as in vector .

Vector vs List — key interview comparison: | | Vector | List | |—|—|—| | Internal implementation | Dynamic array | Doubly
linked list | | Random access ( v[i] ) | ✅ O(1) | ❌ Not supported | | Insert/delete at front | ❌ Costly (O(n)) | ✅ O(1) | | Insert/delete
at back | ✅ Amortized O(1) | ✅ O(1) |

3. Deque — Double Ended Queue

Very similar to list conceptually — operations available at both ends: push_back , push_front , pop_back ,
pop_front , emplace_back , emplace_front .

#include <deque>
deque<int> d;
d.push_back(1);
d.push_front(2);

Careful — don’t confuse two different meanings of “deque”: - deque (the container) = Double Ended Queue. -
“dequeue” (the generic verb) = removing/popping an element from any queue.

List vs Deque — key interview comparison: | | List | Deque | |—|—|—| | Internal implementation | Doubly linked list |
Dynamic array-based | | Random access ( d[i] ) | ❌ Not supported (error) | ✅ Supported (O(1)) |

deque<int> d = {1, 2, 3};


cout << d[1]; // valid — 2

list<int> l = {1, 2, 3};


// cout << l[1]; // ERROR — list doesn't support random access

4. Pair — (from <utility> , part of STL utility library)


Used to group two values together (can be of different types).

pair<int, int> p = {1, 5};


cout << [Link]; // 1
cout << [Link]; // 5

pair<string, int> p2 = {"Shraddha", 21};

Pair of Pairs (nested pairs)

pair<int, pair<int, int>> p = {1, {3, 5}};


cout << [Link]; // 1
cout << [Link]; // 3
cout << [Link]; // 5

Vector of Pairs

vector<pair<int,int>> vp = {{1, 2}, {3, 4}};


for (auto p : vp) {
cout << [Link] << " " << [Link] << endl;
}

// Inserting into a vector of pairs


vp.push_back({4, 5}); // must construct the pair explicitly for push_back
vp.emplace_back(4, 5); // emplace_back builds the pair in-place — no need to pre-construct

Interview one-liner: “ push_back requires an already-constructed object (like a pre-made pair); emplace_back constructs the
object in-place at insertion time, which is why we can just pass 4, 5 directly without wrapping them in {} .”

5. Stack — LIFO (Last In First Out)

Visualize as a stack of books/plates — insert and remove only from the top.

#include <stack>
stack<int> s;
[Link](1);
[Link](2);
[Link](3); // top = 3

cout << [Link](); // 3

[Link](); // removes top element (3)


cout << [Link](); // true/false
cout << [Link]();

// Classic pattern: pop until empty


while (![Link]()) {
cout << [Link]() << " ";
[Link]();
}
// Output: 3 2 1 — REVERSE of insertion order (1,2,3 → pops as 3,2,1)

swap() — swaps contents of two stacks

stack<int> s1, s2;


// ... fill s1 with elements
[Link](s2); // now s1's elements move into s2 and vice versa

Interview one-liner: “Stack is LIFO — last element inserted is the first one removed. push , top , and pop are all O(1).”

6. Queue — FIFO (First In First Out)

Visualize as a real-world line/queue (e.g., at a bank, ticket counter) — insertion happens from the back/rear, removal happens
from the front.
#include <queue>
queue<int> q;
[Link](1);
[Link](2);
[Link](3); // back = 3, front = 1

cout << [Link](); // 1

[Link](); // removes front element (1)

while (![Link]()) {
cout << [Link]() << " ";
[Link]();
}
// Output: 1 2 3 — SAME order as insertion

size() , empty() , swap() work exactly the same as with stack .

Stack vs Queue — quick comparison: | | Stack | Queue | |—|—|—| | Order | LIFO | FIFO | | Insert operation | push() (top) |
push() (back) | | Remove operation | pop() (top) | pop() (front) | | Access | top() | front() (and back() ) |

7. Priority Queue

Internally implemented using a Max Heap (by default) or Min Heap.


Max Heap: the largest element is always at the top (root).
Min Heap: the smallest element is always at the top.
Visualize like a stack, but the element at the “top” always has the highest priority (by default = largest value).

#include <queue>
priority_queue<int> pq; // max-heap by default
[Link](5);
[Link](3);
[Link](10);
[Link](4);

cout << [Link](); // 10 (largest)

while (![Link]()) {
cout << [Link]() << " ";
[Link]();
}
// Output: 10 5 4 3 — always sorted DESCENDING order when popped

Min-Heap version (reverse order)

priority_queue<int, vector<int>, greater<int>> pq;


// `greater<int>` is a functor (function object) used as a custom comparator
[Link](5); [Link](3); [Link](10); [Link](4);
// pops in ascending order: 3 4 5 10

Time complexity (important): | Operation | Stack / Queue | Priority Queue | |—|—|—| | push/pop/top | O(1) | O(log n) —
because internally a tree (heap) is being maintained |

8. Map — Key-Value Pairs

Visualize as a table with two columns: Key and Value.

Key properties (critical, frequently asked): 1. Keys are always unique (no duplicate keys allowed) — think of it like a roll
number or employee ID. 2. Data is automatically stored in sorted order (by key), because map is internally implemented as a
self-balancing binary search tree.
#include <map>
map<string, int> m;
m["TV"] = 100;
m["Laptop"] = 100;
m["Headphones"] = 50;

// If you assign to an existing key, it OVERWRITES the old value (doesn't create a duplicate)
m["TV"] = 150;

for (auto p : m) {
cout << [Link] << " " << [Link] << endl;
}
// Prints in ASCENDING (lexicographic) order of keys: Headphones, Laptop, TV

Map Functions

Function Purpose

[Link]({key, value}) or [Link](key, value) Insert a new key-value pair

Returns 1 if the key exists, 0 if it doesn’t (map has unique keys,


[Link](key)
so it’s always 0 or 1)

m[key] Access/read the value for a key

[Link](key) Removes the entry for that key

[Link](key) Returns an iterator to the key-value pair if found, else [Link]()

[Link]() , [Link]() Same as other containers

[Link]({"Camera", 25});
cout << [Link]("Laptop"); // 1 (exists)

[Link]("TV"); // removes the "TV" entry

auto it = [Link]("Camera");
if (it != [Link]()) cout << "Found";
else cout << "Not found";

Types of Maps

Type Key uniqueness Order Internal structure

Self-balancing BST → O(log n)


map Unique keys Sorted (ascending by key)
operations

multimap Duplicate keys allowed Sorted Self-balancing BST → O(log n)

Hash table → amortized O(1)


unordered_map Unique keys Random/unspecified order
operations

multimap<string, int> mm;


[Link]({"TV", 100});
[Link]({"TV", 200}); // both entries kept! (duplicates allowed)
// mm["key"] square-bracket notation NOT allowed in multimap — must use insert/emplace

unordered_map<string, int> um;


um["Laptop"] = 100;
um["Fridge"] = 200;
// Order when printed is NOT guaranteed / sorted

Interview one-liner: “ map and set are typically implemented as self-balancing BSTs (like Red-Black trees) giving O(log n)
operations; unordered_map / unordered_set use hash tables giving amortized O(1) operations but no ordering guarantee.”

Practical note: unordered_map / unordered_set are used far more frequently in practice/interviews than map / set due to
their faster average time complexity — use map / set specifically when you need sorted order.

9. Set — Unique, Sorted Values

Similar to a mathematical set — stores only unique values in sorted order.


#include <set>
set<int> s;
[Link](1);
[Link](2);
[Link](3);
[Link](1); // duplicate — ignored, size stays same

for (int val : s) cout << val << " "; // 1 2 3 (sorted, unique)
cout << [Link](); // 3

Same core functions as map : count() , erase() , find() , size() , empty() .

lower_bound() and upper_bound() (set-specific, frequently tested)

Function Returns

Iterator to the first element ≥ x (i.e., minimum value that is at


lower_bound(x)
least x )

upper_bound(x) Iterator to the first element > x (strictly greater than x )

set<int> s = {1, 2, 3, 4, 5, 6};

auto lb = s.lower_bound(4); // points to 4 (since 4 exists and is ≥ 4)


cout << *lb; // 4

auto ub = s.upper_bound(4); // points to 5 (first value strictly > 4)


cout << *ub; // 5

// If lower_bound target doesn't exist in the set, e.g. looking for a value
// not present but within range → returns the next larger element.
// If no valid answer exists (target larger than all elements) → returns [Link]()
// dereferencing [Link]() gives garbage/0.

Types of Sets

Type Duplicates Order

set ❌ No Sorted (ascending)

multiset ✅ Yes Sorted

Unordered/random —
unordered_set ❌ No lower_bound / upper_bound don’t
apply (data isn’t sorted)

Interview trap: lower_bound / upper_bound only make logical sense on sorted data — hence they work on
set / multiset / map but not on unordered_set / unordered_map .

10. Algorithms

sort()

#include <algorithm>
int arr[5] = {3, 5, 1, 8, 2};
sort(arr, arr + 5); // ascending order by default

vector<int> v = {3, 5, 1, 8, 2};


sort([Link](), [Link]()); // ascending

The end pointer/iterator passed is always one past the last valid element ( arr + n , or [Link]() ), consistent with the
STL convention.

Sorting in descending order using a comparator

sort(arr, arr + 5, greater<int>()); // NOTE: the () after greater<int> is required!

Common mistake (explicitly called out): forgetting the () after greater<int> — greater<int> alone refers to the type,
greater<int>() creates an actual functor/comparator object to pass into sort .

Custom Comparators (very important, commonly tested)

A comparator is a boolean function that defines the sorting logic — returns true if the first argument should come before the
second.

bool comparator(pair<int,int> p1, pair<int,int> p2) {


// Sort by SECOND value ascending
if ([Link] < [Link]) return true;
if ([Link] > [Link]) return false;
// If second values are equal, sort by FIRST value ascending
if ([Link] < [Link]) return true;
return false;
}

vector<pair<int,int>> vp = {{3,1}, {2,1}, {7,1}, {5,2}};


sort([Link](), [Link](), comparator);
// Sorted by 'second' first; ties broken by 'first'

Interview one-liner: “A custom comparator is a boolean function passed as the third argument to sort() that defines your
own ordering logic — essential when default ascending/descending order isn’t what you need, e.g., sorting pairs by their second
value.”

reverse()

vector<int> v = {1, 2, 3, 4, 5};


reverse([Link](), [Link]()); // reverses the whole vector

reverse([Link]() + 1, [Link]() + 3); // reverses only a sub-range

next_permutation() / prev_permutation()

Generates the next/previous permutation in lexicographic order.

string s = "abc";
next_permutation([Link](), [Link]()); // s becomes "acb"

string s2 = "bca";
prev_permutation([Link](), [Link]()); // s2 becomes "bac"

(Worth knowing how to implement this manually from scratch too — commonly asked as a “no-STL-allowed” interview problem.)

min() / max() / swap()

cout << max(4, 5); // 5


cout << min(6, 10); // 6

int a = 5, b = 10;
swap(a, b); // a=10, b=5

*max_element() / *min_element()

vector<int> v = {3, 5, 1, 8, 2};


cout << *max_element([Link](), [Link]()); // 8
cout << *min_element([Link](), [Link]()); // 1

(Returns an iterator — must dereference with * to get the value.)

binary_search()

vector<int> v = {1, 2, 3, 4, 5}; // must be SORTED


cout << binary_search([Link](), [Link](), 4); // 1 (true) — found
cout << binary_search([Link](), [Link](), 10); // 0 (false) — not found

Returns a boolean (found / not found) — not the index. (In real interviews you’ll usually be asked to implement binary search
manually, but STL’s version is handy to know.)

Bit Manipulation Helpers (GCC built-ins)


int n = 15; // binary: 1111
cout << __builtin_popcount(n); // 4 (counts number of set/1 bits)

long ln = 15;
cout << __builtin_popcountl(ln); // for `long` — note the trailing 'l'

long long lln = 15;


cout << __builtin_popcountll(lln); // for `long long` — trailing 'll'

Interview note: These __builtin_* functions are GCC-compiler-specific (not portable across all C++ compilers), so widely
used in competitive programming but less common in production/industry code.

11. Iterators & Functors — Quick Recap

Concept Meaning

Acts like a pointer to a container’s memory location; used to


Iterator traverse containers, and passed into functions like erase ,
insert , sort , reverse

begin() Points to the first element

end() Points to one-past-the-last element (NOT the last element)

rbegin() Points to the last element (for reverse traversal)

rend() Points to one-before-the-first element

An object that behaves like a function — e.g., greater<int>()


Functor (Function Object)
used as a custom comparator in sort() or priority_queue

Lets the compiler automatically deduce the iterator’s type,


auto keyword
avoiding long/verbose type declarations

12. Time Complexity Cheat Sheet ⭐ (High-yield interview table)

Insert/Delete
Container Insert/Delete (end) Random Access Internal Structure
(middle/front)

vector Amortized O(1) O(n) O(1) Dynamic array

list O(1) O(1) ❌ Not supported Doubly linked list

deque O(1) O(1) at front/back only O(1) Dynamic array-based

Underlying container
stack O(1) (top) — ❌
(deque by default)

Underlying container
queue O(1) (front/back) — ❌
(deque by default)

Max/Min Heap (binary


priority_queue O(log n) — ❌
tree)

map / set O(log n) O(log n) — Self-balancing BST

multimap / multiset O(log n) O(log n) — Self-balancing BST

unordered_map /
Amortized O(1) Amortized O(1) — Hash table
unordered_set

13. Quick-Fire Interview Definitions


Term One-line definition

Standard Template Library — provides ready-made containers

STL and algorithms in C++

Vector Dynamic, resizable array; doubles capacity when full

Sequential container implemented as a doubly linked list;


List
supports front & back operations

Double-ended queue; array-based, supports random access


Deque
unlike list

Pair Groups two values (possibly of different types) together

Stack LIFO structure — insert/remove only from the top

Queue FIFO structure — insert at back, remove from front

Heap-based structure where the highest-priority (by default


Priority Queue
largest) element is always accessible at the top

Map Stores unique key-value pairs in sorted order (by key); BST-based

Unordered Map Same as map but unsorted; hash-table based; faster on average

Set Stores unique values in sorted order

Iterator A pointer-like object used to traverse/access container elements

A function object (like greater<int>() ) passed to customize


Functor
behavior of algorithms

Comparator A boolean function defining custom sort/ordering logic

emplace_back constructs objects in-place; push_back requires


emplace_back vs push_back
an already-constructed object

14. Interview Focus Areas Flagged for Your Prep

Given your priority list (Word Pattern, Missing/Repeated Number, Subarray Sum = K, Valid Parentheses, Kth Largest Element,
Number of Islands/BFS), map these directly to STL containers:

1. Kth Largest Element → use priority_queue (min-heap of size K, or max-heap + pop K-1 times).
2. Number of Islands / BFS → use queue for the BFS traversal.
3. Valid Parentheses → classic stack application (push open brackets, pop/match on close brackets).
4. Subarray Sum Equals K → use unordered_map for prefix-sum frequency counting (O(1) average lookups).
5. Word Pattern → use unordered_map for bidirectional character-to-word mapping.
6. Find Missing AND Repeated Number → can be solved via unordered_map / set counting approach (though optimal
O(1)-space solutions use math/XOR — good to know both).

General interview tips: - Always clarify out loud whether you need sorted order (→ map / set ) or just fast lookup (→
unordered_map / unordered_set ). - Remember [Link]() / [Link]() point one past the last element — a very common off-by-
one/logic trap. - Practice writing a custom comparator from memory — it’s one of the most commonly tested “write it live” STL
skills.

End of notes. Recommended next step: solve 2–3 problems per container (especially priority_queue , unordered_map , and
stack ) to build muscle memory for STL syntax under time pressure.

You might also like