Data Structures & Algorithms Cheatsheet
1. Introduction: The Ultimate Reference Guide
When you are weeks into studying for technical interviews, the sheer volume of information can blur together. Does a PriorityQueue insert in or time? What's the space complexity of Quick Sort? What is the template for Topological Sort?
This cheatsheet serves as a high-density, university-grade reference guide. It condenses the mathematical complexities, core Java APIs, and standard algorithm templates into a single, quickly scannable document. Bookmark this page for rapid review right before your technical interviews.
2. Big-O Complexity Chart
Data Structures
| Data Structure | Access (Avg) | Search (Avg) | Insertion (Avg) | Deletion (Avg) | Space (Worst) | | :--- | :--- | :--- | :--- | :--- | :--- | | Array | | | | | | | Stack / Queue | | | | | | | Singly Linked List | | | | | | | Hash Table | N/A | | | | | | BST | | | | | | | AVL / Red-Black Tree| | | | | | | Min/Max Heap | N/A | | | | | | Trie | | | | | |
(Note: represents the length of the string).
Sorting Algorithms
| Algorithm | Time (Best) | Time (Average) | Time (Worst) | Space (Worst) | Stable? | | :--- | :--- | :--- | :--- | :--- | :--- | | Merge Sort | | | | | Yes | | Quick Sort | | | | | No | | Heap Sort | | | | | No | | Insertion Sort| | | | | Yes | | Counting Sort | | | | | Yes |
(Note: represents the range of the integers).
3. Java Data Structure Syntax
Array & String
// Arrays
int[] arr = new int[5];
Arrays.sort(arr); // O(N log N) Dual-Pivot Quicksort
Arrays.fill(arr, -1); // O(N)
int[] copy = Arrays.copyOf(arr, arr.length); // O(N)
// Strings
String s = "hello";
char c = s.charAt(0); // O(1)
char[] chars = s.toCharArray(); // O(N)
String sub = s.substring(1, 3); // O(N)
Collections
// HashMap
Map<String, Integer> map = new HashMap<>();
map.put("A", 1); // O(1)
map.getOrDefault("B", 0); // O(1)
for (Map.Entry<String, Integer> entry : map.entrySet()) { ... }
// HashSet
Set<Integer> set = new HashSet<>();
set.add(1); // O(1)
set.contains(1); // O(1)
// Queue (LinkedList)
Queue<Integer> q = new LinkedList<>();
q.offer(1); // O(1) Enqueue
q.poll(); // O(1) Dequeue (returns null if empty)
// Stack (ArrayDeque is preferred over legacy Stack)
Deque<Integer> stack = new ArrayDeque<>();
stack.push(1); // O(1) Push
stack.pop(); // O(1) Pop (throws exception if empty)
// Min-Heap (PriorityQueue)
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
minHeap.offer(5); // O(log N)
minHeap.poll(); // O(log N) - Removes minimum
// Max-Heap
PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);
// Or: Collections.reverseOrder()
4. Standard Algorithm Templates
1. Sliding Window (Variable)
Used for finding the longest/shortest subarray that meets a condition.
int left = 0, maxLength = 0;
for (int right = 0; right < arr.length; right++) {
// Add arr[right] to window state
while (/* window state violates condition */) {
// Remove arr[left] from window state
left++;
}
maxLength = Math.max(maxLength, right - left + 1);
}
2. Binary Search
Used for finding an element in a sorted array in time.
int left = 0, right = arr.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) return mid;
else if (arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
3. Graph DFS
Used for exploring all paths or counting connected components.
boolean[] visited = new boolean[N];
public void dfs(int node, List<List<Integer>> adj) {
if (visited[node]) return;
visited[node] = true;
for (int neighbor : adj.get(node)) {
dfs(neighbor, adj);
}
}
4. Graph BFS
Used for finding the shortest path in an unweighted graph.
Queue<Integer> q = new LinkedList<>();
boolean[] visited = new boolean[N];
q.offer(startNode);
visited[startNode] = true;
int steps = 0;
while (!q.isEmpty()) {
int size = q.size(); // Process level by level
for (int i = 0; i < size; i++) {
int curr = q.poll();
if (curr == target) return steps;
for (int neighbor : adj.get(curr)) {
if (!visited[neighbor]) {
visited[neighbor] = true;
q.offer(neighbor);
}
}
}
steps++;
}
5. Backtracking (Combinations/Permutations)
Used for generating all mathematically possible states.
public void backtrack(List<List<Integer>> res, List<Integer> curr, int[] nums, int start) {
// Base Case / Add to result
res.add(new ArrayList<>(curr)); // ALWAYS Deep Copy!
for (int i = start; i < nums.length; i++) {
curr.add(nums[i]); // MAKE CHOICE
backtrack(res, curr, nums, i + 1); // RECURSE
curr.remove(curr.size() - 1); // UNDO CHOICE
}
}
6. Union-Find (Disjoint Set)
Used for instantly checking if two nodes are in the same component.
int[] parent = new int[N];
for(int i = 0; i < N; i++) parent[i] = i;
public int find(int i) {
if (parent[i] == i) return i;
return parent[i] = find(parent[i]); // Path compression
}
public void union(int i, int j) {
int rootI = find(i);
int rootJ = find(j);
if (rootI != rootJ) parent[rootI] = rootJ;
}
5. Identifying the Right Pattern
If you are stuck in an interview, check the constraints and the goal:
- Top/Maximum/Minimum elements
Heap(Priority Queue) - "Contiguous" Subarray/Substring
Sliding Window - Sorted Array + Target Sum
Two Pointers - Sorted Array + requirement
Binary Search - Shortest Path in Unweighted Graph/Matrix
BFS - Shortest Path in Weighted Graph
Dijkstra's - Find all combinations/permutations
Backtracking - Overlapping subproblems (Max/Min ways)
Dynamic Programming - String matching / prefix tracking
Trie - Monotonically increasing/decreasing conditions
Monotonic Stack
6. Interview Checklist
- Clarify: Ask about edge cases. Are there negative numbers? Empty arrays? Can the graph have cycles?
- Brute Force: State the naive solution and its Big-O immediately so you have a baseline.
- Optimize: Discuss trade-offs (Time vs. Space). Suggest HashMaps, Heaps, or Sorting.
- Code: Write clean, modular code. Use descriptive variable names (
currNodenotc). - Test: Dry-run your code with a small example on the whiteboard before the interviewer points out bugs.