An expert-level compilation of Data Structures and Algorithms (DSA). Complexity analysis, tree/graph structures, backtracking, dynamic programming, and dynamic union-find algorithms.
We analyze algorithms by tracking execution bounds relative to input sizes:
Contiguous memory configurations. Accessing offsets is constant, while inserting items requires shifting elements.
Instead of checking nested indices, we maintain boundaries using pointer variables:
// C++ Two-Pointer example: Checking palindrome
#include <iostream>
#include <string>
bool isPalindrome(const std::string& str) {
int left = 0;
int right = str.length() - 1;
while (left < right) {
if (str[left] != str[right]) return false;
left++;
right--;
}
return true;
}
Map keys to bucket index coordinates. Yields fast O(1) average insertions, deletions, and searches.
Data elements (nodes) linked together via pointers.
push, pop, peek.enqueue, dequeue.// BST Node definition
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
Represent nodes (vertices) connected by paths (edges):
Systematically try potential solutions, returning and restoring states if a path fails (e.g. N-Queens, Sudoku).
Make the locally optimal choice at each stage in the hope of finding a global optimum (e.g. Huffman coding, Dijkstra).
Memoize subproblem values to avoid duplicate operations.
// DP Fibonacci (Tabulation)
#include <iostream>
#include <vector>
int fib(int n) {
if (n <= 1) return n;
std::vector<int> dp(n + 1);
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
An array-represented tree used for range query and updates.
// C++ Segment Tree Range Sum Query snippet
#include <vector>
class SegmentTree {
private:
std::vector<int> tree;
int n;
void build(const std::vector<int>& arr, int node, int start, int end) {
if (start == end) {
tree[node] = arr[start];
return;
}
int mid = (start + end) / 2;
build(arr, 2 * node, start, mid);
build(arr, 2 * node + 1, mid + 1, end);
tree[node] = tree[2 * node] + tree[2 * node + 1];
}
public:
SegmentTree(const std::vector<int>& arr) {
n = arr.size();
tree.resize(4 * n, 0);
build(arr, 1, 0, n - 1);
}
};
Maintains partitions of elements, offering fast path compression operations to verify set structures in near-constant time.