HashMap (O(1)) or Binary Search (O(log n))Linked List (O(1)) or Heap (O(log n))Array + Sorting (O(n log n))Heap (O(1) for min/max)Segment Tree or Fenwick Tree (O(log n))In-place sorting (QuickSort, HeapSort)HashMapGraph adjacency list instead of matrixHeap, Linked List, or Balanced BST (e.g., AVL, Red-Black Tree)TreeSet (sorted), Priority Queue (heap)HashSetOrdered Map (e.g., TreeMap in Java)Whenever you're given a problem, ask yourself these four key questions:
| Scenario | Best Data Structure | Why? |
|---|---|---|
| Find top K largest elements | MinHeap (Priority Queue) | Efficient O(k log n) retrieval |
| Check if a number exists in a dataset | HashSet | Fast O(1) lookup |
| Store key-value pairs with fast lookup | HashMap | O(1) access time |
| Process elements in sorted order | TreeSet / Priority Queue | Maintains order dynamically |
| Find shortest path in a graph | Dijkstra’s Algorithm (MinHeap + Graph) | Efficient priority-based traversal |
| Implement LRU Cache | HashMap + Doubly Linked List | Fast lookups + efficient removals |
| Find median in a stream of numbers | Two Heaps (MinHeap & MaxHeap) | Efficient median tracking |
You don’t need to memorize everything—just practice thinking in terms of operations. If you can explain why a data structure is best for a scenario, you’re already thinking like an SDE2!
set Usage and Ordering#include <set> set<int, greater<int>> numbers; // prints in decreasing order set<int> nums2; // prints in ascending order
int val = 12; // value to search
auto it = numbers.find(val);
if(it != numbers.end()){
cout << "found" << endl;
} else {
cout << "not found" << endl;
}
k is much smaller than n.priority_queue<int, vector<int>, greater<int>> minHeap; // min-heap priority_queue<int> maxHeap; // max-heap // For pairs: priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> minheap; // min-heap with pairs priority_queue<pair<int, int>> maxheap; // max-heap with pairs
map vs unordered_map
for(auto it: map_name){
cout << it.first << " " << it.second << " ";
}