Background pattern

Volume 2

Algorithms

Study Notes

Concept reference & formula sheet for this chapter

Searching, Sorting, Hashing, Asymptotic worst case time and Space complexity, Algorithm design techniques: Greedy, Dynamic programming, and Divide-and-conquer, Graph search, Minimum spanning trees, Shortest paths.

Mark Distribution in Previous GATE

Welcome to the "Algorithms" chapter, a cornerstone of Computer Science and a high-scoring section in the GATE examination. This subject delves into the systematic procedures and computational methods used to solve problems, focusing on their efficiency and correctness. Mastering algorithms is crucial not only for theoretical understanding but also for practical application in software development and system design. In GATE CS, algorithms typically carry a significant weightage, often ranging from 10 to 15 marks, with questions spanning theoretical concepts, time and space complexity analysis, problem-solving, and application of various design techniques. Expect a mix of Multiple Choice Questions (MCQ), Multiple Select Questions (MSQ), and Numerical Answer Type (NAT) questions, requiring a deep understanding of underlying principles and the ability to analyze and compare different algorithmic approaches.

Topic-wise Key Concepts

Algorithm Design

Definition: Algorithm design is the process of creating a well-defined computational procedure to solve a specific problem. It involves understanding the problem, choosing appropriate data structures, and devising a step-by-step method that is correct, efficient, and terminates.

Properties/Identities:

  • Correctness: An algorithm must produce the correct output for all valid inputs.

  • Efficiency: Measured by time and space complexity.

  • Finiteness: Must terminate after a finite number of steps.

  • Definiteness: Each step must be precisely defined.

  • Input/Output: Must take zero or more inputs and produce one or more outputs.

Pitfalls/Tricks:

  • Overlooking edge cases or constraints that might break the algorithm's logic.

  • Designing an algorithm that is correct but too inefficient for practical use or given constraints.

Techniques/Shortcuts:

  • Start with a brute-force solution, then optimize.

  • Break down complex problems into smaller, manageable subproblems.

  • Consider different data structures and their impact on performance.

Algorithm Design Techniques

Definition: These are general strategies or paradigms used to develop algorithms for a wide range of problems. Key techniques include Divide and Conquer, Greedy Algorithms, Dynamic Programming, Backtracking, and Branch and Bound.

Properties/Identities:

  • Divide and Conquer: Divide problem into subproblems, solve recursively, combine solutions.

  • Greedy Algorithms: Make locally optimal choices at each step, hoping to find a global optimum.

  • Dynamic Programming: Solves problems with overlapping subproblems and optimal substructure by storing results of subproblems.

Pitfalls/Tricks:

  • Mistaking a problem for one solvable by a greedy approach when it requires dynamic programming.

  • Incorrectly identifying optimal substructure or overlapping subproblems.

Techniques/Shortcuts:

  • For DP, identify the state, recurrence relation, and base cases.

  • For Greedy, prove the greedy choice property and optimal substructure.

Asymptotic Notations

Definition: Mathematical notations used to describe the limiting behavior of a function when the argument tends towards a particular value or infinity, primarily used to classify algorithms by their running time or space requirements as input size grows.

Formulas/Theorems:

  • Big-O Notation (Upper Bound): f(n)=O(g(n))f(n) = O(g(n)) if there exist positive constants cc and n0n_0 such that 0≤f(n)≤c⋅g(n)0 \leq f(n) \leq c \cdot g(n) for all n≥n0n \geq n_0.

  • Omega Notation (Lower Bound): f(n)=Ω(g(n))f(n) = \Omega(g(n)) if there exist positive constants cc and n0n_0 such that 0≤c⋅g(n)≤f(n)0 \leq c \cdot g(n) \leq f(n) for all n≥n0n \geq n_0.

  • Theta Notation (Tight Bound): f(n)=Θ(g(n))f(n) = \Theta(g(n)) if there exist positive constants c1,c2c_1, c_2 and n0n_0 such that 0≤c1⋅g(n)≤f(n)≤c2⋅g(n)0 \leq c_1 \cdot g(n) \leq f(n) \leq c_2 \cdot g(n) for all n≥n0n \geq n_0.

  • Little-o Notation (Strict Upper Bound): f(n)=o(g(n))f(n) = o(g(n)) if lim⁡n→∞f(n)g(n)=0\lim_{n \rightarrow \infty} \frac{f(n)}{g(n)} = 0.

  • Little-omega Notation (Strict Lower Bound): f(n)=ω(g(n))f(n) = \omega(g(n)) if lim⁡n→∞f(n)g(n)=∞\lim_{n \rightarrow \infty} \frac{f(n)}{g(n)} = \infty.

Properties/Identities:

  • Reflexivity: f(n)=O(f(n)),f(n)=Ω(f(n)),f(n)=Θ(f(n))f(n) = O(f(n)), f(n) = \Omega(f(n)), f(n) = \Theta(f(n)).

  • Transitivity: If f(n)=O(g(n))f(n) = O(g(n)) and g(n)=O(h(n))g(n) = O(h(n)), then f(n)=O(h(n))f(n) = O(h(n)). (Applies to all notations).

  • Symmetry: f(n)=Θ(g(n))f(n) = \Theta(g(n)) iff g(n)=Θ(f(n))g(n) = \Theta(f(n)).

  • Transpose Symmetry: f(n)=O(g(n))f(n) = O(g(n)) iff g(n)=Ω(f(n))g(n) = \Omega(f(n)). Similarly for oo and \\omega$.

  • Sum Rule: If f(n)=O(g(n))f(n) = O(g(n)) and h(n)=O(g(n))h(n) = O(g(n)), then f(n)+h(n)=O(g(n))f(n) + h(n) = O(g(n)). (Take the maximum order term).

  • Product Rule: If f(n)=O(g(n))f(n) = O(g(n)) and h(n)=O(p(n))h(n) = O(p(n)), then f(n)⋅h(n)=O(g(n)⋅p(n))f(n) \cdot h(n) = O(g(n) \cdot p(n)).

Pitfalls/Tricks:

  • Confusing Big-O with Theta: Big-O is an upper bound, Theta is a tight bound.

  • Ignoring constants and lower-order terms: Asymptotic notation focuses on growth rate.

  • Assuming O(f(n))O(f(n)) means exactly f(n)f(n) operations; it means "at most proportional to f(n)f(n)".

Techniques/Shortcuts:

  • For polynomials, the highest degree term dominates. E.g., 3n2+5n+10=O(n2)3n^2 + 5n + 10 = O(n^2).

  • Logarithms grow slower than any polynomial: log⁡n=O(nϵ)\log n = O(n^\epsilon) for any ϵ>0\epsilon > 0.

  • Exponentials grow faster than any polynomial: nk=O(an)n^k = O(a^n) for any a>1a > 1.

Bellman Ford

Definition: A single-source shortest path algorithm that can handle graphs with negative edge weights. It works by repeatedly relaxing all edges in the graph, detecting negative cycles if they exist.

Formulas/Theorems:

  • Relaxation Step: For an edge (u,v)(u, v) with weight w(u,v)w(u, v), if d[u]+w(u,v)<d[v]d[u] + w(u, v) < d[v], then d[v]=d[u]+w(u,v)d[v] = d[u] + w(u, v).

  • Number of Iterations: ∣V∣−1|V| - 1 iterations are sufficient to find shortest paths in a graph with ∣V∣|V| vertices, assuming no negative cycles reachable from the source.

  • Negative Cycle Detection: After ∣V∣−1|V| - 1 iterations, if any edge can still be relaxed in the ∣V∣|V|-th iteration, a negative cycle exists.

Properties/Identities:

  • Works on directed and undirected graphs (undirected edges treated as two directed edges).

  • Can detect negative cycles.

  • Time Complexity: O(∣V∣⋅∣E∣)O(|V| \cdot |E|).

  • Space Complexity: O(∣V∣)O(|V|) for distance array, O(∣V∣)O(|V|) for predecessor array.

Pitfalls/Tricks:

  • Incorrectly assuming it's faster than Dijkstra's for non-negative weights (Dijkstra's is O(Elog⁡V)O(E \log V) or O(E+Vlog⁡V)O(E + V \log V)).

  • Forgetting to initialize distances (source to 0, others to infinity).

Techniques/Shortcuts:

  • Visualize the relaxation process step-by-step.

  • For negative cycle detection, run one extra iteration after ∣V∣−1|V| - 1 iterations.

Binary Heap

Definition: A complete binary tree that satisfies the heap property: for a min-heap, every node's value is less than or equal to its children's values; for a max-heap, every node's value is greater than or equal to its children's values.

Typically implemented using an array.

  • Formulas/Theorems:
  • Parent of node ii: ⌊(i−1)/2⌋\lfloor (i - 1) / 2 \rfloor (for 0-indexed array).
  • Left child of node ii: 2i+12i + 1 (for 0-indexed array).
  • Right child of node ii: 2i+22i + 2 (for 0-indexed array).
  • Height of a heap with NN nodes: ⌊log⁡2N⌋\lfloor \log_2 N \rfloor.
  • Properties/Identities:
  • Min-Heap: Root is the minimum element.
  • Max-Heap: Root is the maximum element.
  • Complete Binary Tree: All levels are completely filled except possibly the last level, which is filled from left to right.
  • Operations Time Complexity:
  • ▪ Insert: O(log⁡N)O(\log N)
  • ▪ Delete-Min/Max: O(log⁡N)O(\log N)
  • ▪ Build-Heap (from an array of NN elements): O(N)O(N)
  • Pitfalls/Tricks:
  • Confusing min-heap with max-heap properties.
  • Incorrectly calculating parent/child indices, especially for 1-indexed vs. 0-indexed arrays.
  • Techniques/Shortcuts:
  • When building a heap, start from the last non-leaf node and call heapify upwards.
  • Heap sort uses a max-heap.

Definition: An efficient algorithm for finding an item from a sorted list of items. It repeatedly divides the search interval in half, eliminating half of the remaining elements at each step.

  • Formulas/Theorems:
  • Recurrence Relation: T(N)=T(N/2)+O(1)T(N) = T(N/2) + O(1).
  • Time Complexity: O(log⁡N)O(\log N).
  • Space Complexity: O(1)O(1) (iterative) or O(log⁡N)O(\log N) (recursive due to call stack).
  • Properties/Identities:
  • Requires the input array/list to be sorted.
  • Can be used to find the first/last occurrence of an element, or the ceiling/floor.
  • Pitfalls/Tricks:
  • Forgetting to handle edge cases like empty arrays or target not found.
  • Off-by-one errors in index calculations (e.g., mid = (low + high) / 2). Use mid = low + (high - low) / 2 to prevent overflow.
  • Techniques/Shortcuts:
  • Always ensure the search space is correctly updated (low = mid + 1 or high = mid - 1).
  • For finding first/last occurrence, adjust the update logic to keep searching in the relevant half even after finding a match.

Binary Search Tree (BST)

Definition: A binary tree where for each node, all values in its left subtree are less than the node's value, and all values in its right subtree are greater than the node's value. No duplicate values are typically allowed.

  • Properties/Identities:

  • Inorder Traversal: Produces elements in sorted order.

  • Average Time Complexity:

  • ▪ Search, Insert, Delete: O(log⁡N)O(\log N)

  • Worst-Case Time Complexity (skewed tree):

  • ▪ Search, Insert, Delete: O(N)O(N)

  • Space Complexity: O(N)O(N) for storing nodes.

  • Pitfalls/Tricks:

  • Forgetting to handle the case of deleting a node with two children (replace with inorder successor/predecessor).

  • Assuming O(log⁡N)O(\log N) performance always; a skewed BST degrades to O(N)O(N).

  • Techniques/Shortcuts:

  • To find minimum, traverse left until null. To find maximum, traverse right until null.

  • For deletion, the inorder successor is the smallest node in the right subtree.

Binary Tree

Definition: A tree data structure where each node has at most two children, referred to as the left child and the right child. It's a fundamental non-linear data structure.

Formulas/Theorems:

  • Maximum nodes at level ii (root at level 0): 2i2^i.

  • Maximum nodes in a binary tree of height hh: 2h+1−12^{h+1} - 1.

  • Minimum height of a binary tree with NN nodes: ⌈log⁡2(N+1)⌉−1\lceil \log_2(N + 1) \rceil - 1.

Properties/Identities:

  • Full Binary Tree: Every node has either 0 or 2 children.

  • Complete Binary Tree: All levels are completely filled except possibly the last level, which is filled from left to right.

  • Perfect Binary Tree: All internal nodes have two children and all leaves are at the same level. (A perfect binary tree is always full and complete).

  • Skewed Binary Tree: All nodes have only one child (either left or right).

Pitfalls/Tricks:

  • Confusing different types of binary trees (full, complete, perfect).

  • Incorrectly calculating height or number of nodes for specific tree types.

Techniques/Shortcuts:

  • Understand the relationship between height and number of nodes for different tree types.

  • Practice drawing trees from traversals.

Breadth First Search (BFS)

Definition: A graph traversal algorithm that explores all the neighbor nodes at the present depth before moving on to nodes at the next depth level. It uses a queue data structure.

Properties/Identities:

  • Finds the shortest path in terms of number of edges (unweighted graphs).

  • Guaranteed to visit all reachable vertices.

  • Time Complexity: O(∣V∣+∣E∣)O(|V| + |E|) for adjacency list, O(∣V∣2)O(|V|^2) for adjacency matrix.

  • Space Complexity: O(∣V∣)O(|V|) for queue and visited array.

Pitfalls/Tricks:

  • Forgetting to mark nodes as visited to prevent cycles and redundant processing.

  • Using BFS for weighted shortest paths (Dijkstra's is needed).

Techniques/Shortcuts:

  • Think of BFS as "level-by-level" exploration.

  • Useful for finding connected components, shortest path in unweighted graphs, and checking bipartiteness.

Bubble Sort

Definition: A simple sorting algorithm that repeatedly steps through the list, compares adjacent elements and swaps them if they are in the wrong order. The pass through the list is repeated until no swaps are needed, which indicates that the list is sorted.

Formulas/Theorems:

  • Worst-case Time Complexity: O(N2)O(N^2) (e.g., reverse sorted array).

  • Average-case Time Complexity: O(N2)O(N^2).

  • Best-case Time Complexity: O(N)O(N) (already sorted array, with optimization to stop if no swaps).

  • Space Complexity: O(1)O(1) (in-place).

  • Number of Swaps (Worst Case): N(N−1)/2N(N - 1)/2.

  • Number of Comparisons (Worst Case): N(N−1)/2N(N - 1)/2.

Properties/Identities:

  • Stable sorting algorithm.

  • Adaptive (can detect if an array is sorted and stop early).

Pitfalls/Tricks:

  • Often used as a baseline for comparison due to its simplicity and inefficiency.

  • Not suitable for large datasets.

Techniques/Shortcuts:

  • Understand its passes: after kk passes, the last kk elements are in their correct sorted positions.

Computer Science

Definition: The study of computation and information, including theoretical foundations, algorithmic design, and practical implementation. Algorithms are a core theoretical and practical component.

Properties/Identities:

  • Algorithms are fundamental to all areas of Computer Science.

Depth First Search (DFS)

Definition: A graph traversal algorithm that explores as far as possible along each branch before backtracking. It uses a stack (explicit or implicit via recursion).

Properties/Identities:

  • Can be used to find paths between two nodes, detect cycles, find connected components, and perform topological sorting.

  • Time Complexity: O(∣V∣+∣E∣)O(|V| + |E|) for adjacency list, O(∣V∣2)O(|V|^2) for adjacency matrix.

  • Space Complexity: O(∣V∣)O(|V|) for recursion stack or explicit stack, and visited array.

Pitfalls/Tricks:

  • Can lead to very deep recursion for long paths, potentially causing stack overflow.

  • Does not guarantee shortest paths in unweighted graphs (BFS does).

Techniques/Shortcuts:

  • Think of DFS as "going deep" before "going wide".

  • Useful for cycle detection, topological sort, and finding strongly connected components.

Dijkstra's Algorithm

Definition: A single-source shortest path algorithm for graphs with non-negative edge weights. It uses a greedy approach and a priority queue to efficiently find the shortest paths from a source vertex to all other vertices.

Formulas/Theorems:

  • Relaxation Step: Same as Bellman-Ford.

Time Complexity:

  • ▪ With min-priority queue (binary heap): O(∣E∣log⁡∣V∣)O(|E| \log |V|) or O(∣E∣+∣V∣log⁡∣V∣)O(|E| + |V| \log |V|) if using Fibonacci heap.

  • ▪ With adjacency matrix (no priority queue, simple array scan): O(∣V∣2)O(|V|^2).

  • Space Complexity: O(∣V∣+∣E∣)O(|V| + |E|) for graph, O(∣V∣)O(|V|) for distances/predecessors.

Properties/Identities:

  • Does not work correctly with negative edge weights.

  • Greedy algorithm.

  • Guaranteed to find the shortest path.

Pitfalls/Tricks:

  • Applying it to graphs with negative edge weights (use Bellman-Ford instead).

  • Forgetting to update distances in the priority queue (decrease-key operation).

Techniques/Shortcuts:

  • Always pick the unvisited vertex with the smallest known distance.

  • Visualize the "settling" of vertices.

Directed Acyclic Graph (DAG)

Definition: A directed graph that contains no directed cycles. This property makes them useful for representing processes with dependencies, like task scheduling.

Properties/Identities:

  • Can always be topologically sorted.

  • No path can revisit a vertex.

  • Every finite DAG has at least one source (in-degree 0) and at least one sink (out-degree 0).

Pitfalls/Tricks:

  • Confusing DAGs with general directed graphs that might have cycles.

  • Trying to apply algorithms that assume cycles (e.g., finding strongly connected components) without

modification.

  • Techniques/Shortcuts:
  • Topological sort is a key algorithm for DAGs.
  • Dynamic programming problems on graphs often involve DAGs.

Double Hashing

Definition: A collision resolution technique in hashing that uses two hash functions. When a collision occurs with the first hash function, the second hash function is used to determine the step size for probing the hash table.

  • Formulas/Theorems:
  • Primary Hash Function: h1(k)h_1(k).
  • Secondary Hash Function: h2(k)h_2(k). h2(k)h_2(k) must never return 0. Often h2(k)=R−(k(modR))h_2(k) = R - (k \pmod R) for a prime R<table_sizeR < \text{table\_size}.
  • Probe Sequence: h(k,i)=(h1(k)+i⋅h2(k))(modM)h(k, i) = (h_1(k) + i \cdot h_2(k)) \pmod M, where MM is table size and ii is probe number (0, 1, 2, ...).
  • Properties/Identities:
  • Minimizes clustering compared to linear probing.
  • Provides better distribution of keys.
  • Requires h2(k)h_2(k) to be relatively prime to MM to ensure all slots are probed.
  • Pitfalls/Tricks:
  • Choosing a secondary hash function that can return 0 or is not relatively prime to the table size, leading to incomplete probing.
  • Incorrectly implementing the modulo operation for negative results.
  • Techniques/Shortcuts:
  • Ensure MM is a prime number and RR is a prime smaller than MM for h2(k)=R−(k(modR))h_2(k) = R - (k \pmod R).

Dynamic Programming

Definition: An algorithmic technique for solving complex problems by breaking them down into simpler subproblems. It's applicable when subproblems overlap and the problem exhibits optimal substructure. Solutions to subproblems are stored to avoid recomputation (memoization or tabulation).

  • Properties/Identities:
  • Optimal Substructure: An optimal solution to the problem contains optimal solutions to its subproblems.
  • Overlapping Subproblems: The same subproblems are encountered multiple times.
  • Memoization (Top-down): Store results of subproblems as they are computed.
  • Tabulation (Bottom-up): Solve subproblems in a specific order, typically filling a table.
  • Pitfalls/Tricks:
  • Incorrectly identifying the state of the DP problem.
  • Formulating an incorrect recurrence relation.
  • Forgetting base cases or handling them improperly.
  • Techniques/Shortcuts:
  • Define the state: What information is needed to solve a subproblem?
  • Formulate the recurrence relation: How can a subproblem be solved using solutions to smaller subproblems?
  • Identify base cases.
  • Choose between memoization (recursive with caching) and tabulation (iterative).

Graph Algorithms

Definition: A category of algorithms designed to solve problems on graphs, which are mathematical structures used to model pairwise relations between objects. This includes traversal, shortest path, minimum spanning tree, and connectivity problems.

  • Properties/Identities:

  • Common representations: Adjacency matrix, adjacency list.

  • Key problems: Shortest Path, MST, Graph Traversal, Connectivity.

  • Pitfalls/Tricks:

  • Not considering graph type (directed/undirected, weighted/unweighted, cyclic/acyclic) when choosing an algorithm.

  • Memory limitations for dense graphs with adjacency matrices.

  • Techniques/Shortcuts:

  • Always consider the graph representation that best suits the problem and its constraints.

  • Practice drawing graphs and tracing algorithms.

Definition: Algorithms for systematically visiting all vertices and edges in a graph. The two primary methods are Breadth-First Search (BFS) and Depth-First Search (DFS).

Properties/Identities:

  • BFS: Level-by-level, uses queue, finds shortest path in unweighted graphs.

  • DFS: Explores deeply, uses stack/recursion, useful for cycle detection, topological sort, SCC.

Pitfalls/Tricks:

  • Forgetting to use a 'visited' array/set to prevent infinite loops in cyclic graphs.

  • Choosing the wrong search algorithm for the problem (e.g., DFS for unweighted shortest path).

Techniques/Shortcuts:

  • BFS is good for finding "closest" elements.

  • DFS is good for exploring "all paths" or "connectivity".

Greedy Algorithms

Definition: An algorithmic paradigm that makes the locally optimal choice at each stage with the hope of finding a global optimum. It doesn't always guarantee the globally optimal solution but works for specific problems.

Properties/Identities:

  • Greedy Choice Property: A globally optimal solution can be reached by making a locally optimal (greedy) choice.

  • Optimal Substructure: An optimal solution to the problem contains optimal solutions to its subproblems.

Pitfalls/Tricks:

  • Applying greedy approach to problems where it doesn't yield an optimal solution (e.g., general shortest path with negative weights, 0/1 Knapsack).

  • Not proving the greedy choice property and optimal substructure.

Techniques/Shortcuts:

  • Common examples: Dijkstra's, Prim's, Kruskal's, Huffman Coding.

  • Try to prove correctness by contradiction or exchange argument.

Hashing

Definition: A technique used to map data of arbitrary size to fixed-size values (hash codes), typically used for efficient data retrieval in hash tables. Involves a hash function and collision resolution strategies.

Formulas/Theorems:

  • Hash Function: h(k)=k(modM)h(k) = k \pmod M (division method), h(k)=⌊M(kA(mod1))⌋h(k) = \lfloor M(kA \pmod 1) \rfloor (multiplication method).

  • Load Factor: α=N/M\alpha = N/M, where NN is number of items, MM is table size.

Properties/Identities:

  • Collision: When two different keys map to the same hash value.

  • Collision Resolution: Open addressing (linear probing, quadratic probing, double hashing) or Separate chaining.

  • Average Time Complexity (Search, Insert, Delete): O(1)O(1) (with good hash function and low load factor).

  • Worst-case Time Complexity: O(N)O(N) (due to collisions).

Pitfalls/Tricks:

  • Choosing a poor hash function that leads to many collisions (e.g., for string keys, summing ASCII values).

  • Ignoring the impact of load factor on performance.

Techniques/Shortcuts:

  • For division method, choose MM as a prime number not too close to a power of 2 or 10.

  • Understand the trade-offs between different collision resolution techniques.

Heap Sort

Definition: A comparison-based sorting algorithm that uses a binary heap data structure. It's an in-place algorithm that first builds a max-heap from the input data and then repeatedly extracts the maximum element and rebuilds the heap.

Formulas/Theorems:

  • Time Complexity: O(Nlog⁡N)O(N \log N) for all cases (best, average, worst).

  • Space Complexity: O(1)O(1) (in-place).

Properties/Identities:

  • Not a stable sorting algorithm.

  • Uses a max-heap.

  • Build-heap step takes O(N)O(N) time.

  • NN extractions take N⋅O(log⁡N)N \cdot O(\log N) time.

Pitfalls/Tricks:

  • Confusing the heap property (min-heap vs. max-heap) with the sorting order.

  • Incorrectly implementing the heapify procedure.

Techniques/Shortcuts:

  • Remember the two phases: build heap, then extract max and heapify.

  • The largest element is always at the root after heapify.

Huffman Code

Definition: A particular type of optimal prefix code used for lossless data compression. It's a greedy algorithm that builds a binary tree based on the frequencies of characters, assigning shorter codes to more frequent characters.

Properties/Identities:

  • Prefix Code: No code is a prefix of another code, allowing unambiguous decoding.

  • Optimal: Produces the minimum possible expected code word length for a given set of character frequencies.

  • Uses a min-priority queue to repeatedly combine the two lowest-frequency nodes.

  • Time Complexity: O(Nlog⁡N)O(N \log N) where NN is the number of unique characters.

Pitfalls/Tricks:

  • Incorrectly building the Huffman tree (e.g., not using a min-priority queue, or incorrect combination logic).

  • Forgetting that it's a greedy algorithm.

Techniques/Shortcuts:

  • Always combine the two nodes with the smallest frequencies.

  • The path from the root to a leaf defines the code word (e.g., left=0, right=1).

Identify Function

Definition: In a general mathematical or programming context, an identity function (often denoted idid or II) is a function that always returns the same value that was used as its argument. f(x)=xf(x) = x. In algorithms, it might refer to a function used to uniquely identify elements or properties.

Properties/Identities:

  • For any input xx, f(x)=xf(x) = x.

  • It's the neutral element for function composition: (f∘id)(x)=f(x)(f \circ id)(x) = f(x) and (id∘f)(x)=f(x)(id \circ f)(x) = f(x).

Pitfalls/Tricks:

  • This term is very generic; in an algorithmic context, it's usually implied or part of a larger concept (e.g., an identity hash function, or an identity matrix).

Insertion Sort

Definition: A simple sorting algorithm that builds the final sorted array (or list) one item at a time. It iterates through the input elements and removes one element at a time, finds the place where it belongs within the already sorted part, and inserts it there.

Formulas/Theorems:

  • Worst-case Time Complexity: O(N2)O(N^2) (e.g., reverse sorted array).

  • Average-case Time Complexity: O(N2)O(N^2).

  • Best-case Time Complexity: O(N)O(N) (already sorted array).

  • Space Complexity: O(1)O(1) (in-place).

  • Number of Swaps (Worst Case): N(N−1)/2N(N - 1)/2.

  • Number of Comparisons (Worst Case): N(N−1)/2N(N - 1)/2.

Properties/Identities:

  • Stable sorting algorithm.

  • Adaptive (efficient for nearly sorted arrays).

  • Good for small datasets.

Pitfalls/Tricks:

  • Inefficient for large, unsorted arrays.

  • Understanding the "shift" operation correctly.

Techniques/Shortcuts:

  • Think of it like sorting a hand of playing cards.

  • The first element is considered sorted.

Inversion

Definition: In an array AA, an inversion is a pair of indices (i,j)(i, j) such that i<ji < j and A[i]>A[j]A[i] > A[j]. It measures how "unsorted" an array is.

Formulas/Theorems:

  • Maximum number of inversions in an array of size NN: N(N−1)/2N(N - 1)/2 (for a reverse-sorted array).

  • Minimum number of inversions: 0 (for a sorted array).

Properties/Identities:

  • The number of inversions can be counted efficiently using a modified Merge Sort algorithm in O(Nlog⁡N)O(N \log N) time.

Pitfalls/Tricks:

  • Confusing inversions with just any pair of elements that are out of order; the index order i<ji < j is crucial.

Techniques/Shortcuts:

  • To count inversions, adapt Merge Sort: when merging two sorted halves, if an element from the right half is taken before an element from the left half, it means all remaining elements in the left half form inversions with the taken element.

Linear Probing

Definition: A collision resolution technique in open addressing hashing where, upon a collision, the algorithm searches for the next available slot sequentially in the hash table (e.g., at h(k)+1,h(k)+2,…h(k) + 1, h(k) + 2, \dots).

Formulas/Theorems:

  • Probe Sequence: h(k,i)=(h(k)+i)(modM)h(k, i) = (h(k) + i) \pmod{M}, where MM is table size and ii is probe number (0, 1, 2, ...).

Properties/Identities:

  • Simple to implement.

  • Suffers from primary clustering: long runs of occupied slots build up, increasing average search time.

Pitfalls/Tricks:

  • Primary clustering significantly degrades performance, especially at high load factors.

  • Deletion is tricky: simply removing an element can break search chains. Often requires "lazy deletion" or re-hashing.

Techniques/Shortcuts:

  • Understand that it's the simplest but often least efficient open addressing method.

Matrix Chain Ordering (Matrix Chain Multiplication)

Definition: A dynamic programming problem that seeks to find the most efficient way to multiply a sequence of matrices. The problem is not about performing the multiplications, but deciding the optimal parenthesization (order) to minimize the total number of scalar multiplications.

Formulas/Theorems:

  • Recurrence Relation: Let M[i,j]M[i, j] be the minimum number of scalar multiplications needed to compute the product AiAi+1…AjA_i A_{i+1} \dots A_j.

M[i,j]=min⁡i≤k<j(M[i,k]+M[k+1,j]+pi−1pkpj)M[i, j] = \min_{i \leq k < j} (M[i, k] + M[k + 1, j] + p_{i-1} p_k p_j)

where AiA_i has dimensions pi−1×pip_{i-1} \times p_i.

  • Base Case: M[i,i]=0M[i, i] = 0 (single matrix requires no multiplications).

  • Time Complexity: O(N3)O(N^3) for NN matrices.

  • Space Complexity: O(N2)O(N^2) for the DP table.

Properties/Identities:

  • Exhibits optimal substructure and overlapping subproblems.

  • The order of multiplication matters for efficiency, not for the result.

Pitfalls/Tricks:

  • Incorrectly setting up the dimensions array pp. If there are NN matrices A1,…,ANA_1, \dots, A_N, and AiA_i is pi−1×pip_{i-1} \times p_i, then the array pp has N+1N + 1 elements.

  • Off-by-one errors in the recurrence relation indices.

Techniques/Shortcuts:

  • Fill the DP table diagonally, starting with chain length 2, then 3, and so on.

Maximum Minimum

Definition: The problem of finding both the maximum and minimum elements in a given array or list. This can be done naively by iterating twice or more efficiently using a divide and conquer approach.

Formulas/Theorems:

  • Naive Approach (2N-2 comparisons): Iterate once for max, once for min.

Divide and Conquer Approach (approx. 3N/2 comparisons):

  • ▪ If array size is 1, max=min=element.

  • ▪ If array size is 2, compare once.

  • ▪ Recursively find max/min in two halves, then compare the two maxes and two mins.

Properties/Identities:

  • The divide and conquer approach is more efficient in terms of comparisons.

Pitfalls/Tricks:

  • Forgetting to handle base cases (array of size 1 or 2) correctly in recursive solutions.

Techniques/Shortcuts:

  • Pairwise comparison: process elements in pairs, comparing them. Then compare the smaller of the pair with the current min, and the larger with the current max. This also achieves approx. 3N/2 comparisons.

Merge Sort

Definition: A divide and conquer sorting algorithm that divides an unsorted list into NN sublists, each containing one element (a list of one element is considered sorted), then repeatedly merges sublists to produce new sorted sublists until there is only one sorted list remaining.

Formulas/Theorems:

  • Recurrence Relation: T(N)=2T(N/2)+O(N)T(N) = 2T(N/2) + O(N) (for dividing and merging).

  • Time Complexity: O(Nlog⁡N)O(N \log N) for all cases (best, average, worst).

  • Space Complexity: O(N)O(N) (due to auxiliary array for merging).

Properties/Identities:

  • Stable sorting algorithm.

  • Not an in-place algorithm (requires extra space).

  • Well-suited for external sorting.

Pitfalls/Tricks:

  • Incorrectly implementing the merging step, which is crucial for correctness and efficiency.

  • Forgetting to copy remaining elements from one half if the other half is exhausted during merge.

Techniques/Shortcuts:

  • The merge step is the core: combine two sorted arrays into one sorted array.

  • Can be used to count inversions.

Merging

Definition: The process of combining two or more sorted lists (or arrays) into a single sorted list. This is a fundamental operation in algorithms like Merge Sort.

Formulas/Theorems:

  • Time Complexity: O(N+M)O(N + M) to merge two sorted lists of sizes NN and MM.

  • Space Complexity: O(N+M)O(N + M) for the new merged list.

Properties/Identities:

  • Requires input lists to be sorted.

  • The output list is also sorted.

Pitfalls/Tricks:

  • Off-by-one errors when handling array boundaries and indices.

  • Not correctly handling the case where one list is exhausted before the other.

Techniques/Shortcuts:

  • Use two pointers, one for each input list, and a third pointer for the merged list.

Minimum Spanning Tree (MST)

Definition: For a connected, undirected, weighted graph, an MST is a subgraph that is a tree, connects all the vertices together, and has the minimum possible total edge weight. Algorithms include Prim's and Kruskal's.

  • Formulas/Theorems:
  • Cut Property: For any cut (partition of vertices into two sets), if an edge crosses the cut and has strictly less weight than any other edge crossing the cut, then this edge must be in every MST.
  • Cycle Property: If an edge is the heaviest edge in any cycle of a graph, then it cannot be part of an MST.
  • An MST of a graph with ∣V∣|V| vertices always has ∣V∣−1|V| - 1 edges.
  • Properties/Identities:
  • Both Prim's and Kruskal's are greedy algorithms.
  • Prim's: Grows the MST from a starting vertex.
  • Kruskal's: Adds edges in increasing order of weight, avoiding cycles.
  • Pitfalls/Tricks:
  • Applying MST algorithms to disconnected graphs (they will find an MST for each connected component, forming a Minimum Spanning Forest).
  • Confusing MST with shortest path problems.
  • Techniques/Shortcuts:
  • Prim's uses a min-priority queue.
  • Kruskal's uses a Disjoint Set Union (DSU) data structure.

Number of Swap

Definition: A metric used to evaluate the efficiency of certain sorting algorithms, particularly comparison sorts. It counts how many times elements are exchanged during the sorting process.

  • Formulas/Theorems:
  • Bubble Sort (Worst Case): N(N−1)/2N(N - 1)/2.
  • Selection Sort (Worst Case): N−1N - 1.
  • Insertion Sort (Worst Case): N(N−1)/2N(N - 1)/2.
  • Quick Sort (Worst Case): O(N2)O(N^2) swaps.
  • Heap Sort (Worst Case): O(Nlog⁡N)O(N \log N) swaps.
  • Properties/Identities:
  • A lower number of swaps generally indicates better performance, especially when swap operations are costly.
  • Selection sort performs the minimum number of swaps among simple sorts.
  • Pitfalls/Tricks:
  • Confusing swaps with comparisons. Both are important metrics but measure different aspects.
  • Techniques/Shortcuts:
  • Memorize the worst-case swap counts for common sorting algorithms.

Prims Algorithm

Definition: A greedy algorithm that finds a Minimum Spanning Tree (MST) for a weighted undirected graph. It starts from an arbitrary vertex and grows the MST by adding the cheapest edge that connects a vertex in the MST to a vertex outside the MST.

  • Formulas/Theorems:
  • Time Complexity:
  • ▪ With adjacency matrix (simple array scan): O(∣V∣2)O(|V|^2).
  • ▪ With adjacency list and binary min-priority queue: O(∣E∣log⁡∣V∣)O(|E| \log |V|) or O(∣E∣+∣V∣log⁡∣V∣)O(|E| + |V| \log |V|).
  • Space Complexity: O(∣V∣+∣E∣)O(|V| + |E|) for graph, O(∣V∣)O(|V|) for distances/parent array.
  • Properties/Identities:
  • Greedy algorithm.
  • Builds the MST by adding vertices one by one.
  • Similar structure to Dijkstra's algorithm.
  • Pitfalls/Tricks:
  • Forgetting to update edge weights in the priority queue when a shorter path to an unvisited vertex is found.
  • Applying to directed graphs (MST is for undirected graphs).
  • Techniques/Shortcuts:
  • Maintain a set of vertices already in the MST and a min-priority queue of edges connecting to vertices outside

the MST.

Quick Sort

Definition: A highly efficient, in-place, divide and conquer sorting algorithm. It works by selecting a 'pivot' element from the array and partitioning the other elements into two sub-arrays, according to whether they are less than or greater than the pivot. The sub-arrays are then sorted recursively.

Formulas/Theorems:

  • Worst-case Time Complexity: O(N2)O(N^2) (e.g., already sorted array with first/last element as pivot).
  • Average-case Time Complexity: O(Nlog⁡N)O(N \log N).
  • Best-case Time Complexity: O(Nlog⁡N)O(N \log N).
  • Space Complexity: O(log⁡N)O(\log N) (average, for recursion stack) or O(N)O(N) (worst-case, for recursion stack).
  • Recurrence Relation (Average Case): T(N)=T(k)+T(N−k−1)+O(N)T(N) = T(k) + T(N - k - 1) + O(N), where kk is the size of one partition. For balanced partitions, T(N)=2T(N/2)+O(N)T(N) = 2T(N/2) + O(N).

Properties/Identities:

  • Not a stable sorting algorithm.
  • In-place sorting algorithm.
  • Performance heavily depends on pivot selection.

Pitfalls/Tricks:

  • Poor pivot selection can lead to O(N2)O(N^2) performance.
  • Incorrect partitioning logic can lead to infinite recursion or incorrect sorting.

Techniques/Shortcuts:

  • Randomized pivot selection helps achieve average-case performance reliably.
  • Hoare's partition scheme is often more efficient than Lomuto's.

Recurrence Relation

Definition: An equation that recursively defines a sequence or function, where each term or value is given as a function of preceding terms. Used to describe the time complexity of recursive algorithms.

Formulas/Theorems:

  • Master Theorem: For recurrences of the form T(N)=aT(N/b)+f(N)T(N) = aT(N/b) + f(N) where a≥1,b>1a \geq 1, b > 1.
    1. If f(N)=O(Nlog⁡ba−ϵ)f(N) = O(N^{\log_b a - \epsilon}) for some ϵ>0\epsilon > 0, then T(N)=Θ(Nlog⁡ba)T(N) = \Theta(N^{\log_b a}).
    1. If f(N)=Θ(Nlog⁡ba)f(N) = \Theta(N^{\log_b a}), then T(N)=Θ(Nlog⁡balog⁡N)T(N) = \Theta(N^{\log_b a} \log N).
    1. If f(N)=Ω(Nlog⁡ba+ϵ)f(N) = \Omega(N^{\log_b a + \epsilon}) for some ϵ>0\epsilon > 0, AND af(N/b)≤cf(N)af(N/b) \leq cf(N) for some c<1c < 1 and large NN, then T(N)=Θ(f(N))T(N) = \Theta(f(N)).

Properties/Identities:

  • Describes the growth rate of recursive algorithms.
  • Methods to solve: Substitution, Recursion Tree, Master Theorem.

Pitfalls/Tricks:

  • Incorrectly applying the Master Theorem (e.g., when f(N)f(N) doesn't fit any case or the regularity condition is not met).
  • Algebraic errors in substitution or recursion tree methods.

Techniques/Shortcuts:

  • Memorize the three cases of the Master Theorem.
  • For simple recurrences, try expanding a few terms to find a pattern.

Recursion

Definition: A programming technique where a function calls itself directly or indirectly to solve a problem. It involves a base case (stopping condition) and a recursive step (reducing the problem to a smaller instance of itself).

Properties/Identities:

  • Base Case: A condition that terminates the recursion.
  • Recursive Step: The function calls itself with a modified (smaller) input.
  • Often leads to elegant and concise code for problems with recursive structure.

Pitfalls/Tricks:

  • Missing or incorrect base case leading to infinite recursion (stack overflow).
  • High space complexity due to recursion stack.
  • Performance overhead compared to iterative solutions due to function call stack management.

Techniques/Shortcuts:

  • Always identify the base case first.

  • Ensure that each recursive call moves closer to the base case.

  • For some problems, recursion can be converted to iteration using a stack.

Searching

Definition: The process of finding a specific item (or items) within a collection of items. Common search algorithms include Linear Search and Binary Search.

Formulas/Theorems:

  • Linear Search (Worst Case): O(N)O(N) comparisons.

  • Binary Search (Worst Case): O(log⁡N)O(\log N) comparisons.

Properties/Identities:

  • Linear Search: Works on unsorted or sorted data.

  • Binary Search: Requires sorted data.

Pitfalls/Tricks:

  • Using Linear Search on a large sorted array when Binary Search is applicable.

  • Errors in Binary Search boundary conditions.

Techniques/Shortcuts:

  • Always check if data is sorted before choosing a search algorithm.

Selection Sort

Definition: A simple sorting algorithm that repeatedly finds the minimum element from the unsorted part of the list and swaps it with the element at the current position. It maintains two subarrays: sorted and unsorted.

Formulas/Theorems:

  • Worst-case Time Complexity: O(N2)O(N^2).

  • Average-case Time Complexity: O(N2)O(N^2).

  • Best-case Time Complexity: O(N2)O(N^2).

  • Space Complexity: O(1)O(1) (in-place).

  • Number of Swaps (All Cases): N−1N - 1 (minimum possible swaps for any comparison sort).

  • Number of Comparisons (All Cases): N(N−1)/2N(N - 1)/2.

Properties/Identities:

  • Not a stable sorting algorithm.

  • Performs the minimum number of swaps among simple sorts.

Pitfalls/Tricks:

  • Its performance is consistently O(N2)O(N^2) regardless of input order, unlike Bubble Sort or Insertion Sort.

Techniques/Shortcuts:

  • The key idea is to find the minimum and place it, then find the next minimum and place it, and so on.

Shortest Path

Definition: The problem of finding a path between two vertices (or from a source to all other vertices) in a graph such that the sum of the weights of its constituent edges is minimized. Algorithms include BFS (unweighted), Dijkstra's (non-negative weights), and Bellman-Ford (negative weights).

Properties/Identities:

  • Unweighted Graphs: BFS finds shortest path in terms of number of edges.

  • Non-negative Weighted Graphs: Dijkstra's algorithm.

  • Negative Weighted Graphs (no negative cycles): Bellman-Ford algorithm.

  • All-Pairs Shortest Path: Floyd-Warshall algorithm.

Pitfalls/Tricks:

  • Using the wrong algorithm for the given graph properties (e.g., Dijkstra's on negative weights).

  • Not handling disconnected components or unreachable vertices.

Techniques/Shortcuts:

  • Always check for negative edge weights and negative cycles.

  • Understand the relaxation principle.

Sorting

Definition: The process of arranging elements of a list or array in a specific order (e.g., numerical, alphabetical, ascending, descending). It's a fundamental operation in computer science.

  • Formulas/Theorems:
  • Comparison Sort Lower Bound: Any comparison-based sorting algorithm requires Ω(Nlog⁡N)\Omega(N \log N) comparisons in the worst case.
  • Properties/Identities:
  • Stable Sort: Preserves the relative order of equal elements.
  • In-place Sort: Requires O(1)O(1) or O(log⁡N)O(\log N) auxiliary space.
  • Adaptive Sort: Performance improves for partially sorted input.
  • Pitfalls/Tricks:
  • Confusing different sorting algorithm properties (stability, in-place, worst-case vs. average-case).
  • Choosing an inefficient sort for specific data characteristics.
  • Techniques/Shortcuts:
  • Know the time and space complexities, stability, and in-place nature of common sorts.
  • For GATE, often questions involve comparing two sorts or analyzing a modified sort.

Space Complexity

Definition: A measure of the amount of memory an algorithm needs to run to completion. It includes the space required for input, output, and temporary variables, often expressed using asymptotic notation.

  • Properties/Identities:
  • Auxiliary Space: The extra space used by the algorithm beyond the input data.
  • In-place Algorithm: An algorithm that transforms input using only a small, constant amount of auxiliary space, typically O(1)O(1) or O(log⁡N)O(\log N) for recursion stack.
  • Pitfalls/Tricks:
  • Forgetting to account for the recursion stack space in recursive algorithms.
  • Confusing total space with auxiliary space.
  • Techniques/Shortcuts:
  • Identify data structures created by the algorithm (arrays, queues, stacks, hash tables).
  • For recursive calls, the maximum depth of the recursion stack contributes to space complexity.

Strongly Connected Components (SCC)

Definition: In a directed graph, a strongly connected component (SCC) is a maximal subgraph such that for every pair of vertices uu and vv in the subgraph, there is a path from uu to vv and a path from vv to uu. Algorithms include Kosaraju's and Tarjan's.

  • Properties/Identities:
  • SCCs partition the vertices of a directed graph.
  • If we contract each SCC into a single vertex, the resulting graph is a Directed Acyclic Graph (DAG).
  • Kosaraju's Algorithm: Two DFS passes (one on original graph, one on transpose graph).
  • Tarjan's Algorithm: One DFS pass, uses discovery times and low-link values.
  • Formulas/Theorems:
  • Time Complexity (Kosaraju's, Tarjan's): O(∣V∣+∣E∣)O(|V| + |E|).
  • Pitfalls/Tricks:
  • Confusing SCCs with connected components in undirected graphs.
  • Incorrectly performing DFS on the transpose graph for Kosaraju's.
  • Techniques/Shortcuts:
  • Kosaraju's: DFS on G to get finishing times, then DFS on G transpose in decreasing order of finishing times.
  • Tarjan's: Uses a stack and disc (discovery time) and low (lowest discovery time reachable) arrays.

Time Complexity

Definition: A measure of the amount of time an algorithm takes to run as a function of the length of its input. It's typically expressed using asymptotic notations (Big-O, Omega, Theta).

  • Properties/Identities:
  • Focuses on the growth rate of operations as input size NN increases.
  • Usually refers to worst-case time complexity, but average-case and best-case are also important.
  • Independent of machine specifics (CPU speed, memory access time).

Pitfalls/Tricks:

  • Confusing constant factors with asymptotic growth.

  • Incorrectly analyzing loops or recursive calls.

  • Assuming best-case performance for general analysis.

Techniques/Shortcuts:

  • Count dominant operations (comparisons, assignments, arithmetic operations).

  • For nested loops, multiply loop counts.

  • For recursive functions, use recurrence relations and Master Theorem.

Topological Sort

Definition: A linear ordering of vertices in a Directed Acyclic Graph (DAG) such that for every directed edge (u,v)(u, v), vertex uu comes before vertex vv in the ordering. Not unique for all DAGs.

Properties/Identities:

  • Only possible for DAGs.

  • Can be implemented using DFS or Kahn's algorithm (using in-degrees and a queue).

  • Time Complexity: O(∣V∣+∣E∣)O(|V| + |E|).

Pitfalls/Tricks:

  • Attempting to topologically sort a graph with cycles (it's impossible).

  • Incorrectly handling multiple possible topological sorts.

Techniques/Shortcuts:

  • DFS-based: Perform DFS, then reverse the order of finishing times.

  • Kahn's Algorithm: Find all nodes with in-degree 0, add to queue. While queue not empty, dequeue, add to sorted list, decrement in-degree of neighbors. If neighbor's in-degree becomes 0, enqueue.

Tree Traversal

Definition: The process of visiting each node in a tree data structure exactly once. Common methods include Inorder, Preorder, Postorder (for binary trees), and Level-order traversal.

Properties/Identities:

  • Inorder (Left-Root-Right): For BSTs, gives sorted elements.

  • Preorder (Root-Left-Right): Useful for creating a copy of the tree.

  • Postorder (Left-Right-Root): Useful for deleting a tree.

  • Level-order (BFS-like): Visits nodes level by level, uses a queue.

  • Time Complexity: O(N)O(N) for a tree with NN nodes.

  • Space Complexity: O(H)O(H) for DFS-based (recursion stack, where HH is height), O(W)O(W) for BFS-based (queue, where WW is max width).

Pitfalls/Tricks:

  • Confusing the order of visits for different traversal types.

  • Incorrectly handling null nodes in recursive traversals.

Techniques/Shortcuts:

  • Practice drawing the traversal paths on sample trees.

  • Remember the "Root" position in the name (Pre-Root-Order, In-Root-Order, Post-Root-Order).

Uniform Hashing

Definition: An idealized theoretical model for hashing where each key is equally likely to hash to any slot in the hash table, independent of where other keys hash. It implies a perfectly random distribution of keys.

Properties/Identities:

  • Assumed for theoretical analysis of hashing algorithms (e.g., average case performance of open addressing).

  • Difficult to achieve in practice with real-world data.

  • Minimizes collisions and maximizes efficiency.

Pitfalls/Tricks:

  • Assuming practical hash functions achieve uniform hashing, which is rarely true.

  • Not understanding that it's a theoretical ideal, not a practical hash function.

Techniques/Shortcuts:

  • When analyzing hashing, remember that uniform hashing is the best-case scenario for collision distribution.

Quick Formula Reference

Asymptotic Notations:

  • Big-O: f(n)=O(g(n))  ⟹  ∃c,n0>0 s.t. 0≤f(n)≤c⋅g(n) for n≥n0f(n) = O(g(n)) \implies \exists c, n_0 > 0 \text{ s.t. } 0 \leq f(n) \leq c \cdot g(n) \text{ for } n \geq n_0.

  • Omega: f(n)=Ω(g(n))  ⟹  ∃c,n0>0 s.t. 0≤c⋅g(n)≤f(n) for n≥n0f(n) = \Omega(g(n)) \implies \exists c, n_0 > 0 \text{ s.t. } 0 \leq c \cdot g(n) \leq f(n) \text{ for } n \geq n_0.

  • Theta: f(n)=Θ(g(n))  ⟹  ∃c1,c2,n0>0 s.t. 0≤c1⋅g(n)≤f(n)≤c2⋅g(n) for n≥n0f(n) = \Theta(g(n)) \implies \exists c_1, c_2, n_0 > 0 \text{ s.t. } 0 \leq c_1 \cdot g(n) \leq f(n) \leq c_2 \cdot g(n) \text{ for } n \geq n_0.

Binary Heap:

  • Parent of ii (0-indexed): ⌊(i−1)/2⌋\lfloor (i - 1)/2 \rfloor.

  • Left child of ii: 2i+12i + 1.

  • Right child of ii: 2i+22i + 2.

  • Height: ⌊log⁡2N⌋\lfloor \log_2 N \rfloor.

Binary Tree:

  • Max nodes at level ii: 2i2^i.

  • Max nodes in height hh: 2h+1−12^{h+1} - 1.

  • Min height with NN nodes: ⌈log⁡2(N+1)⌉−1\lceil \log_2(N + 1) \rceil - 1.

Hashing (Open Addressing):

  • Linear Probing: h(k,i)=(h(k)+i)(modM)h(k, i) = (h(k) + i) \pmod M.

  • Double Hashing: h(k,i)=(h1(k)+i⋅h2(k))(modM)h(k, i) = (h_1(k) + i \cdot h_2(k)) \pmod M.

  • Load Factor: α=N/M\alpha = N/M.

Matrix Chain Ordering:

M[i,j]=min⁡i≤k<j(M[i,k]+M[k+1,j]+pi−1pkpj)M[i, j] = \min_{i \leq k < j} (M[i, k] + M[k + 1, j] + p_{i-1}p_kp_j)

Base Case: M[i,i]=0M[i, i] = 0.

  • Recurrence Relation (Master Theorem): T(N)=aT(N/b)+f(N)T(N) = aT(N/b) + f(N).

    1. If f(N)=O(Nlog⁡ba−ϵ)f(N) = O(N^{\log_b a - \epsilon}), T(N)=Θ(Nlog⁡ba)T(N) = \Theta(N^{\log_b a}).
    1. If f(N)=Θ(Nlog⁡ba)f(N) = \Theta(N^{\log_b a}), T(N)=Θ(Nlog⁡balog⁡N)T(N) = \Theta(N^{\log_b a} \log N).
    1. If f(N)=Ω(Nlog⁡ba+ϵ)f(N) = \Omega(N^{\log_b a + \epsilon}) and af(N/b)≤cf(N)af(N/b) \leq cf(N), T(N)=Θ(f(N))T(N) = \Theta(f(N)).

Sorting Algorithm Complexities:

Graph Algorithm Complexities (Adjacency List):

  • BFS: O(∣V∣+∣E∣)O(|V| + |E|)

  • DFS: O(∣V∣+∣E∣)O(|V| + |E|)

  • Dijkstra's (Binary Heap): O(∣E∣log⁡∣V∣)O(|E| \log |V|)

  • Bellman-Ford: O(∣V∣⋅∣E∣)O(|V| \cdot |E|)

  • Prim's (Binary Heap): O(∣E∣log⁡∣V∣)O(|E| \log |V|)

  • Kruskal's (DSU): O(∣E∣log⁡∣E∣)O(|E| \log |E|) or O(∣E∣log⁡∣V∣)O(|E| \log |V|)

  • Topological Sort: O(∣V∣+∣E∣)O(|V| + |E|)

  • SCC (Kosaraju's/Tarjan's): O(∣V∣+∣E∣)O(|V| + |E|)

Important Tips for GATE

    1. Master Asymptotic Notations: A significant portion of algorithm questions revolves around time and space complexity. Understand the definitions of O,Ω,Θ,o,ωO, \Omega, \Theta, o, \omega thoroughly, and be adept at applying them to various code snippets and recurrence relations, especially using the Master Theorem.
    1. Understand Algorithm Design Paradigms: Don't just memorize algorithms; understand why they work and which paradigm they belong to (Divide and Conquer, Greedy, Dynamic Programming). This helps in identifying the correct approach for new problems.
    1. Practice Recurrence Relations: Solving recurrence relations is a frequently tested skill. Be comfortable with the substitution method, recursion tree method, and especially the Master Theorem. Pay attention to base cases and boundary conditions.
    1. Graph Algorithms are Crucial: BFS, DFS, Dijkstra's, Bellman-Ford, Prim's, Kruskal's, Topological Sort, and SCCs are high-yield topics. Know their complexities, applications, and limitations (e.g., negative weights for