WILSY / LEARN

Understand the pattern.
Solve the next problem.

Your DSA roadmap, with room to think. Explore the connections, practise the essentials and build a record of what you have mastered.

01

Find a pattern

Follow a branch or search the explorer.

02

Practise with context

Read the idea, then open a recommended problem.

03

Build your progress

Mark what you understand. Come back to the rest.

YOUR LEARNING WORKSPACE

The DSA roadmap

0 / 127mastered0%

Progress is saved in this browser. No account needed to learn.

Drag to explore · Ctrl + scroll to zoom

Mastery progress

0 of 127 completed (0%)

0%

All categories

127
Browse the complete pattern reference without the mind-map
Opposite ends (left + right) Array

Two pointers start on opposite ends and move inwards. Crucial for sorted arrays to search pairs or validate palindromes.

  • LeetCode 167: Two Sum II
  • LeetCode 125: Valid Palindrome
  • LeetCode 11: Container With Most Water
def two_sum_opposite(arr, target):
    left, right = 0, len(arr) - 1
    while left < right:
        curr_sum = arr[left] + arr[right]
        if curr_sum == target:
            return [left, right]
        elif curr_sum < target:
            left += 1
        else:
            right -= 1
    return []
Same direction (fast & slow pointers) Array

Two pointers move at different rates or offsets in the same direction. Useful for removing duplicates or partitioning in-place.

  • LeetCode 26: Remove Duplicates
  • LeetCode 283: Move Zeroes
  • LeetCode 80: Remove Duplicates II
def move_zeroes(nums):
    slow = 0
    for fast in range(len(nums)):
        if nums[fast] != 0:
            nums[slow], nums[fast] = nums[fast], nums[slow]
            slow += 1
Partition / Dutch flag Array

Maintains three pointers (low, mid, high) to group elements into three separate ranges in O(N) time and O(1) space.

  • LeetCode 75: Sort Colors
  • LeetCode 905: Sort Array By Parity
def sort_colors(nums):
    low, mid, high = 0, 0, len(nums) - 1
    while mid <= high:
        if nums[mid] == 0:
            nums[low], nums[mid] = nums[mid], nums[low]
            low += 1; mid += 1
        elif nums[mid] == 1:
            mid += 1
        else:
            nums[mid], nums[high] = nums[high], nums[mid]
            high -= 1
Fixed Size Array

Maintains a fixed subsegment width K as it slides across the array, tracking statistics on elements entering and leaving.

  • LeetCode 643: Maximum Average Subarray I
  • LeetCode 1456: Maximum Vowels in Substring
def max_vowels_fixed(s, k):
    vowels = set("aeiou")
    curr_count = sum(1 for c in s[:k] if c in vowels)
    max_count = curr_count
    for i in range(k, len(s)):
        if s[i] in vowels: curr_count += 1
        if s[i - k] in vowels: curr_count -= 1
        max_count = max(max_count, curr_count)
    return max_count
Expand–Shrink Array

Expands the right bound to add elements, and shrinks the left bound dynamically when constraints are violated.

  • LeetCode 209: Minimum Size Subarray Sum
  • LeetCode 3: Longest Substring Without Repeating Characters
def min_subarray_len(target, nums):
    left, curr_sum = 0, 0
    min_len = float('inf')
    for right in range(len(nums)):
        curr_sum += nums[right]
        while curr_sum >= target:
            min_len = min(min_len, right - left + 1)
            curr_sum -= nums[left]
            left += 1
    return min_len if min_len != float('inf') else 0
Monotonic Window Array

Combines a sliding window with a monotonic deque to fetch extreme boundary values inside window frames in O(1) time.

  • LeetCode 239: Sliding Window Maximum
  • LeetCode 1438: Longest Continuous Subarray Limit
from collections import deque
def max_sliding_window(nums, k):
    q = deque()
    res = []
    for i, x in enumerate(nums):
        while q and nums[q[-1]] <= x: q.pop()
        q.append(i)
        if q[0] == i - k: q.popleft()
        if i >= k - 1: res.append(nums[q[0]])
    return res
Prefix Sum Array

Precomputes aggregate sums to answer subarray range queries [L, R] in O(1) time.

  • LeetCode 303: Range Sum Query
  • LeetCode 525: Contiguous Array
  • LeetCode 560: Subarray Sum Equals K
class NumArray:
    def __init__(self, nums):
        self.prefix = [0] * (len(nums) + 1)
        for i in range(len(nums)):
            self.prefix[i + 1] = self.prefix[i] + nums[i]
    def sum_range(self, left, right):
        return self.prefix[right + 1] - self.prefix[left]
Prefix XOR Array

Tracks cumulative XOR outputs to support range XOR sweeps and bitwise complement lookups in constant time.

  • LeetCode 1310: XOR Queries of a Subarray
  • LeetCode 1442: Count Triplets XOR
def xor_queries(arr, queries):
    prefix = [0] * (len(arr) + 1)
    for i in range(len(arr)):
        prefix[i + 1] = prefix[i] ^ arr[i]
    return [prefix[r + 1] ^ prefix[l] for l, r in queries]
2D Prefix Array

Precomputes matrix area ranges, supporting subgrid summation updates in constant time.

  • LeetCode 304: Range Sum Query 2D - Immutable
class NumMatrix:
    def __init__(self, matrix):
        R, C = len(matrix), len(matrix[0])
        self.dp = [[0] * (C + 1) for _ in range(R + 1)]
        for r in range(R):
            for c in range(C):
                self.dp[r+1][c+1] = matrix[r][c] + self.dp[r][c+1] + self.dp[r+1][c] - self.dp[r][c]
    def sum_region(self, r1, c1, r2, c2):
        return self.dp[r2+1][c2+1] - self.dp[r1][c2+1] - self.dp[r2+1][c1] + self.dp[r1][c1]
Max subarray sum (Kadane's) Array

Maintains a running maximum sum. Resets current sum to 0 if it dips negative. Updates a global max.

  • LeetCode 53: Maximum Subarray
  • LeetCode 918: Maximum Sum Circular Subarray
def max_subarray(nums):
    max_so_far = curr = nums[0]
    for x in nums[1:]:
        curr = max(x, curr + x)
        max_so_far = max(max_so_far, curr)
    return max_so_far
Max product subarray Array

Maintains running minimum and maximum products at each node to handle double negative product inversions.

  • LeetCode 152: Maximum Product Subarray
def max_product(nums):
    res = max(nums)
    curr_min = curr_max = 1
    for x in nums:
        if x == 0:
            curr_min = curr_max = 1
            continue
        tmp = curr_max * x
        curr_max = max(x * curr_max, x * curr_min, x)
        curr_min = min(tmp, x * curr_min, x)
        res = max(res, curr_max)
    return res
Subarray with given XOR / sum Array

Pairs cumulative prefix XOR counts inside hash maps to locate count target intervals matching X ^ Y = Target.

  • LeetCode 560: Subarray Sum Equals K
  • GeeksforGeeks: Subarrays with XOR K
def subarrays_with_xor(arr, k):
    prefix_counts = {0: 1}
    curr_xor = 0
    ans = 0
    for x in arr:
        curr_xor ^= x
        target = curr_xor ^ k
        if target in prefix_counts:
            ans += prefix_counts[target]
        prefix_counts[curr_xor] = prefix_counts.get(curr_xor, 0) + 1
    return ans
on index Array

Performs O(log N) splits on sorted indices using lower/upper bounds based on median values.

  • LeetCode 704: Binary Search
  • LeetCode 34: Find First and Last Position
def binary_search(arr, target):
    l, r = 0, len(arr) - 1
    while l <= r:
        mid = l + (r - l) // 2
        if arr[mid] == target: return mid
        elif arr[mid] < target: l = mid + 1
        else: r = mid - 1
    return -1
on answer Array

Searches an abstract continuous answer space utilizing monotonic validation checks to minimize/maximize configurations.

  • LeetCode 875: Koko Eating Bananas
  • LeetCode 1011: Capacity To Ship Packages
def can_ship(capacity, weights, days):
    curr, count = 0, 1
    for w in weights:
        if curr + w > capacity:
            count += 1; curr = w
        else: curr += w
    return count <= days
Longest substring without repeat String

Maintains a sliding window where duplicates shrink the left border dynamically to ensure unique elements.

  • LeetCode 3: Longest Substring Without Repeating Characters
def length_of_longest_substring(s):
    seen = {}
    l = max_len = 0
    for r, c in enumerate(s):
        if c in seen and seen[c] >= l:
            l = seen[c] + 1
        seen[c] = r
        max_len = max(max_len, r - l + 1)
    return max_len
Minimum window substring String

Maintains character counts inside a sliding window, expanding rightwards to find match requirements and shrinking leftwards to trim.

  • LeetCode 76: Minimum Window Substring
from collections import Counter
def min_window(s, t):
    need = Counter(t)
    window = {}
    have, need_len = 0, len(need)
    res, res_len = [-1, -1], float('inf')
    l = 0
    for r, c in enumerate(s):
        if c in need:
            window[c] = window.get(c, 0) + 1
            if window[c] == need[c]: have += 1
        while have == need_len:
            if (r - l + 1) < res_len:
                res = [l, r]; res_len = r - l + 1
            left_c = s[l]
            if left_c in need:
                window[left_c] -= 1
                if window[left_c] < need[left_c]: have -= 1
            l += 1
    return s[res[0]:res[1]+1] if res_len != float('inf') else ""
Anagram / permutation in string String

Slides a fixed window of size T on string S, validating if counts maps match the target string.

  • LeetCode 438: Find All Anagrams
  • LeetCode 567: Permutation in String
def check_inclusion(s1, s2):
    if len(s1) > len(s2): return False
    c1, c2 = [0]*26, [0]*26
    for i in range(len(s1)):
        c1[ord(s1[i]) - 97] += 1
        c2[ord(s2[i]) - 97] += 1
    matches = sum(1 for i in range(26) if c1[i] == c2[i])
    for i in range(len(s1), len(s2)):
        if matches == 26: return True
        # Slide window logic...
        pass
    return matches == 26
Palindrome check String

Compares alphanumeric characters moving inwards from outer ends, skipping spacing and casing differences.

  • LeetCode 125: Valid Palindrome
  • LeetCode 680: Valid Palindrome II
def is_palindrome(s):
    l, r = 0, len(s) - 1
    while l < r:
        while l < r and not s[l].isalnum(): l += 1
        while l < r and not s[r].isalnum(): r -= 1
        if s[l].lower() != s[r].lower(): return False
        l, r = l + 1, r - 1
    return True
Reverse words / characters String

Applies two-pointer swaps outwards/inwards to reverse characters or isolated word strings in-place.

  • LeetCode 151: Reverse Words in a String
  • LeetCode 344: Reverse String
def reverse_string(s):
    l, r = 0, len(s) - 1
    while l < r:
        s[l], s[r] = s[r], s[l]
        l += 1; r -= 1
String compression String

Compresses repeating characters in-place using read and write pointers to record characters and counts.

  • LeetCode 443: String Compression
def compress(chars):
    write = read = 0
    while read < len(chars):
        c = chars[read]
        cnt = 0
        while read < len(chars) and chars[read] == c:
            read += 1; cnt += 1
        chars[write] = c; write += 1
        if cnt > 1:
            for digit in str(cnt):
                chars[write] = digit; write += 1
    return write
KMP (failure function) String

Speeds up substring matching in O(N+M) time by precomputing a Longest Prefix Suffix (LPS) helper to bypass redundancies.

  • LeetCode 28: Index of First Occurrence
def compute_lps(pat):
    lps = [0] * len(pat)
    j = 0
    for i in range(1, len(pat)):
        while j > 0 and pat[i] != pat[j]: j = lps[j-1]
        if pat[i] == pat[j]: j += 1; lps[i] = j
    return lps
Rabin-Karp (rolling hash) String

Evaluates rolling hashes of sliding text windows to locate matching pattern values in average O(N+M) time.

  • LeetCode 187: Repeated DNA Sequences
def rolling_hash(s, l):
    # compute hash in window length L
    pass
Z-algorithm String

Constructs prefix matching Z-arrays linearly by mirroring bounds calculated over matches.

  • LeetCode 2223: Sum of Scores of Built Strings
def get_z_array(s):
    z = [0] * len(s)
    l = r = 0
    for i in range(1, len(s)):
        if i <= r: z[i] = min(r - i + 1, z[i - l])
        while i + z[i] < len(s) and s[z[i]] == s[i + z[i]]: z[i] += 1
        if i + z[i] - 1 > r: l, r = i, i + z[i] - 1
    return z
Frequency Based Hash map

Tabulates character or integer occurrences inside hash maps to handle top-k lists and uniqueness checks.

  • LeetCode 387: First Unique Character
  • LeetCode 347: Top K Frequent Elements
def frequency_map(nums):
    counts = {}
    for x in nums: counts[x] = counts.get(x, 0) + 1
    return counts
Lookup Based Hash map

Performs O(1) checks for matching complements or key existence to skip nested loops.

  • LeetCode 1: Two Sum
  • LeetCode 217: Contains Duplicate
def contains_duplicate(nums):
    seen = set()
    for x in nums:
        if x in seen: return True
        seen.add(x)
    return False
Set Based Hash map

Identifies custom continuous coordinate sweeps utilizing Hash Sets to achieve linear lookups.

  • LeetCode 128: Longest Consecutive Sequence
def longest_consec(nums):
    num_set = set(nums)
    max_len = 0
    for x in nums:
        if x - 1 not in num_set:
            curr = x; curr_len = 1
            while curr + 1 in num_set:
                curr += 1; curr_len += 1
            max_len = max(max_len, curr_len)
    return max_len
Index Mapping Hash map

Maps key values directly to earliest or latest array index positions to calculate subarray bounds.

  • LeetCode 525: Contiguous Array
  • LeetCode 325: Maximum Size Subarray Sum Equals k
def max_sub_array_len(nums, k):
    lookup = {0: -1}
    curr_sum = max_len = 0
    for i, x in enumerate(nums):
        curr_sum += x
        if curr_sum - k in lookup:
            max_len = max(max_len, i - lookup[curr_sum - k])
        if curr_sum not in lookup:
            lookup[curr_sum] = i
    return max_len
Grouping Pattern Hash map

Groups array items inside a hash map using a standardized signature or sorted representation as key values.

  • LeetCode 49: Group Anagrams
def group_anagrams(strs):
    ans = {}
    for s in strs:
        key = "".join(sorted(s))
        ans.setdefault(key, []).append(s)
    return list(ans.values())
Increasing Stack

Stack keeps elements in strictly increasing values, useful for finding nearest smaller elements.

  • LeetCode 84: Largest Rectangle in Histogram
def increasing_stack(arr):
    stack = []
    for i, x in enumerate(arr):
        while stack and stack[-1] > x:
            stack.pop()
        stack.append(x)
Decreasing Stack

Stack keeps elements in strictly decreasing values, useful for finding nearest greater elements.

  • LeetCode 739: Daily Temperatures
def daily_temp(T):
    ans = [0] * len(T)
    stack = []
    for i, x in enumerate(T):
        while stack and T[stack[-1]] < x:
            idx = stack.pop()
            ans[idx] = i - idx
        stack.append(i)
    return ans
Next Greater Stack

Walks array to resolve the next element on the right possessing a larger value.

  • LeetCode 496: Next Greater Element I
  • LeetCode 503: Next Greater Element II
def next_greater(nums):
    res = [-1] * len(nums)
    stack = []
    for i in range(len(nums)):
        while stack and nums[stack[-1]] < nums[i]:
            res[stack.pop()] = nums[i]
        stack.append(i)
    return res
Next Smaller Stack

Resolves the index of the first smaller element on the right using a monotonic increasing stack.

  • LeetCode 84: Largest Rectangle (Next Smaller boundaries)
def next_smaller(arr):
    # monotonic increasing indices pop resolver
    pass
Previous Variants Stack

Iterates elements from left-to-right (or right-to-left) to resolve adjacent previous boundaries in a single sweep.

  • LeetCode 901: Online Stock Span
class StockSpanner:
    def __init__(self):
        self.stack = [] # (price, span)
    def next(self, price):
        span = 1
        while self.stack and self.stack[-1][0] <= price:
            span += self.stack.pop()[1]
        self.stack.append((price, span))
        return span
Range / Span Stack

Identifies numeric subsegment spans where elements remain larger or smaller than reference values.

  • LeetCode 901: Online Stock Span
def calculate_spans(prices):
    stack = [] # stack of indices
    spans = []
    for i, p in enumerate(prices):
        while stack and prices[stack[-1]] <= p: stack.pop()
        spans.append(i + 1 if not stack else i - stack[-1])
        stack.append(i)
    return spans
min/Max Stack Stack

Supports retrieval of minimum/maximum elements in O(1) time by caching adjacent active minimums.

  • LeetCode 155: Min Stack
class MinStack:
    def __init__(self):
        self.stack = []
        self.min_stack = []
    def push(self, x):
        self.stack.append(x)
        if not self.min_stack or x <= self.min_stack[-1]: self.min_stack.append(x)
    def pop(self):
        if self.stack.pop() == self.min_stack[-1]: self.min_stack.pop()
    def getMin(self): return self.min_stack[-1]
Expression Handling Stack

Parses mathematical brackets and operator sequences recursively or using stacks.

  • LeetCode 224: Basic Calculator
  • LeetCode 150: Evaluate Reverse Polish Notation
def eval_rpn(tokens):
    stack = []
    for t in tokens:
        if t not in "+-*/": stack.append(int(t))
        else:
            r, l = stack.pop(), stack.pop()
            if t == '+': stack.append(l + r)
            elif t == '-': stack.append(l - r)
            elif t == '*': stack.append(l * r)
            elif t == '/': stack.append(int(l / r))
    return stack[0]
Histogram Pattern Stack

Tracks monotonic index boundaries to determine max areas bounded by heights.

  • LeetCode 84: Largest Rectangle in Histogram
  • LeetCode 85: Maximal Rectangle
def largest_rectangle_area(heights):
    heights.append(0)
    stack = [-1]
    ans = 0
    for i, h in enumerate(heights):
        while stack and heights[stack[-1]] > h:
            height = heights[stack.pop()]
            width = i - stack[-1] - 1
            ans = max(ans, height * width)
        stack.append(i)
    return ans
FIFO Processing QUEUE / DEQUE

Processes data streams dynamically in first-in-first-out order, preserving chronological ordering.

  • LeetCode 933: Number of Recent Calls
from collections import deque
class RecentCounter:
    def __init__(self):
        self.q = deque()
    def ping(self, t: int) -> int:
        self.q.append(t)
        while self.q[0] < t - 3000:
            self.q.popleft()
        return len(self.q)
Level-wise Processing QUEUE / DEQUE

Implements tree or graph Breadth-First Searches by expanding nodes level by level using a FIFO queue.

  • LeetCode 102: Level Order Traversal
  • LeetCode 199: Binary Tree Right Side View
def right_side_view(root):
    if not root: return []
    res = []
    q = deque([root])
    while q:
        level_len = len(q)
        for i in range(level_len):
            node = q.popleft()
            if i == level_len - 1: res.append(node.val)
            if node.left: q.append(node.left)
            if node.right: q.append(node.right)
    return res
Circular Queue Pattern QUEUE / DEQUE

Maintains fixed-size buffers using dual pointers wrapping modulo capacity limits to process continuous streams.

  • LeetCode 622: Design Circular Queue
class MyCircularQueue:
    def __init__(self, k: int):
        self.q = [0]*k
        self.head = self.tail = self.size = 0
        self.cap = k
Deque Based QUEUE / DEQUE

Supports quick insertions and deletions on both outer boundaries, key to solving sliding window extremes.

  • LeetCode 239: Sliding Window Maximum
from collections import deque
def clean_deque(dq, i, k, nums):
    if dq and dq[0] == i - k: dq.popleft()
    while dq and nums[dq[-1]] < nums[i]: dq.pop()
Fast–Slow LINKED LIST

Employs two pointers moving at different speeds to locate lists nodes.

  • LeetCode 876: Middle of List
def get_middle(head):
    slow = fast = head
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
    return slow
Cycle Detection LINKED LIST

Detects linked list loops in constant space by checking if fast and slow pointers overlap.

  • LeetCode 141: Linked List Cycle
  • LeetCode 142: Linked List Cycle II
def has_cycle(head):
    slow = fast = head
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast: return True
    return False
Finding Middle LINKED LIST

Divides list subsegments dynamically utilizing midpoint indicators as splits in sorting routines.

  • LeetCode 148: Sort List (Merge Sort midpoints)
def split_list(head):
    # returns middle node for merge splits
    pass
Full Reverse LINKED LIST

Reverses a list in O(N) time and O(1) space by pointing nodes backwards.

  • LeetCode 206: Reverse Linked List
def reverse_list(head):
    prev = None
    curr = head
    while curr:
        nxt = curr.next
        curr.next = prev
        prev = curr
        curr = nxt
    return prev
Partial (k-group) LINKED LIST

Reverses list segments of length K iteratively, preserving connections across segments.

  • LeetCode 25: Reverse Nodes in k-Group
  • LeetCode 92: Reverse Linked List II
def reverse_k_group(head, k):
    curr = head
    count = 0
    while curr and count < k:
        curr = curr.next; count += 1
    if count == k:
        prev = reverse_k_group(curr, k)
        curr = head
        for _ in range(k):
            nxt = curr.next
            curr.next = prev
            prev = curr
            curr = nxt
        return prev
    return head
Merge Lists LINKED LIST

Combines sorted linked lists by comparing head pointer nodes and stitching recursively.

  • LeetCode 21: Merge Two Sorted Lists
  • LeetCode 23: Merge K Sorted Lists
def merge_two(l1, l2):
    dummy = ListNode()
    curr = dummy
    while l1 and l2:
        if l1.val < l2.val:
            curr.next = l1; l1 = l1.next
        else:
            curr.next = l2; l2 = l2.next
        curr = curr.next
    curr.next = l1 or l2
    return dummy.next
DFS (Pre / In / Post order) TREES

Recursive and iterative searches covering root and child branches systematically.

  • LeetCode 94: Inorder
  • LeetCode 144: Preorder
  • LeetCode 145: Postorder
def dfs_inorder(node):
    if not node: return
    dfs_inorder(node.left)
    print(node.val)
    dfs_inorder(node.right)
BFS (Level Order/ zigzag/ right side view) TREES

Explores nodes level-by-level horizontally using FIFO queues.

  • LeetCode 102: Level Order
  • LeetCode 103: Zigzag Traversal
def level_order(root):
    if not root: return []
    q, res = deque([root]), []
    while q:
        level = []
        for _ in range(len(q)):
            node = q.popleft()
            level.append(node.val)
            if node.left: q.append(node.left)
            if node.right: q.append(node.right)
        res.append(level)
    return res
Top Down approach TREES

Passes parameters down to child nodes recursively to calculate properties from top bounds.

  • LeetCode 112: Path Sum
  • LeetCode 129: Sum Root to Leaf Numbers
def sum_numbers(root, curr=0):
    if not root: return 0
    curr = curr * 10 + root.val
    if not root.left and not root.right: return curr
    return sum_numbers(root.left, curr) + sum_numbers(root.right, curr)
Bottom Up approach TREES

Retrieves answers from child nodes bottom-up, synthesizing combined properties at the parent level.

  • LeetCode 110: Balanced Binary Tree
  • LeetCode 236: Lowest Common Ancestor
def lca(root, p, q):
    if not root or root == p or root == q: return root
    left = lca(root.left, p, q)
    right = lca(root.right, p, q)
    if left and right: return root
    return left or right
Max path sum TREES

Finds max root-to-root or leaf-to-leaf paths bottom-up, keeping track of global maximums.

  • LeetCode 124: Binary Tree Maximum Path Sum
def max_path_sum(root):
    self.ans = float('-inf')
    def get_max(node):
        if not node: return 0
        left = max(0, get_max(node.left))
        right = max(0, get_max(node.right))
        self.ans = max(self.ans, node.val + left + right)
        return node.val + max(left, right)
    get_max(root)
    return self.ans
Diameter/Height / depth TREES

Calculates dimensions recursively at each node to track long paths bounded by root connections.

  • LeetCode 543: Diameter of Tree
  • LeetCode 104: Maximum Depth
def diameter(root):
    self.d = 0
    def height(node):
        if not node: return 0
        l, r = height(node.left), height(node.right)
        self.d = max(self.d, l + r)
        return 1 + max(l, r)
    height(root)
    return self.d
BST (Binary Search Tree) TREES

Exploits Binary Search Tree property (left children < root < right children) to perform search operations.

  • LeetCode 98: Validate BST
  • LeetCode 235: LCA of a BST
def validate_bst(root, min_val=float('-inf'), max_val=float('inf')):
    if not root: return True
    if not (min_val < root.val < max_val): return False
    return (validate_bst(root.left, min_val, root.val) and 
            validate_bst(root.right, root.val, max_val))
Decision Tree Recursion

Branches recursively over possible choices, drawing decision paths down recursively.

  • LeetCode 17: Letter Combinations of a Phone Number
def letter_combinations(digits):
    if not digits: return []
    mapping = {"2": "abc", "3": "def"} # etc.
    res = []
    def backtrack(idx, path):
        if idx == len(digits):
            res.append("".join(path)); return
        for char in mapping[digits[idx]]:
            path.append(char)
            backtrack(idx + 1, path)
            path.pop()
    backtrack(0, [])
    return res
Choose–Explore–Unchoose Recursion

Backtracking framework: select candidate, trigger recursion, then revert selection state.

  • LeetCode 39: Combination Sum
def backtrack(start, target, path):
    if target == 0:
        res.append(path[:]); return
    for i in range(start, len(candidates)):
        if candidates[i] > target: continue
        path.append(candidates[i])
        backtrack(i, target - candidates[i], path) # choose + explore
        path.pop() # unchoose
Subsets (power set) Recursion

Generates power subsets recursively by choosing to either include or exclude the current element.

  • LeetCode 78: Subsets
  • LeetCode 90: Subsets II
def subsets(nums):
    res = []
    def solve(idx, curr):
        if idx == len(nums):
            res.append(curr[:]); return
        curr.append(nums[idx])
        solve(idx + 1, curr)
        curr.pop()
        solve(idx + 1, curr)
    solve(0, [])
    return res
PermutationsCombinations (nCr) Recursion

Produces element permutations recursively, tracking used indicators to prevent index overlaps.

  • LeetCode 46: Permutations
  • LeetCode 77: Combinations
def permute(nums):
    res = []
    def backtrack(start):
        if start == len(nums):
            res.append(nums[:]); return
        for i in range(start, len(nums)):
            nums[start], nums[i] = nums[i], nums[start]
            backtrack(start + 1)
            nums[start], nums[i] = nums[i], nums[start]
    backtrack(0)
    return res
Word search on grid Recursion

Runs 4-directional DFS searches on matrix grids, flagging active nodes and clearing marks upon backtrack splits.

  • LeetCode 79: Word Search
def dfs(r, c, idx):
    if idx == len(word): return True
    if not (0<=r<R and 0<=c<C) or board[r][c] != word[idx]: return False
    tmp, board[r][c] = board[r][c], "#"
    ans = (dfs(r+1,c,idx+1) or dfs(r-1,c,idx+1) or dfs(r,c+1,idx+1) or dfs(r,c-1,idx+1))
    board[r][c] = tmp
    return ans
Palindrome partitioning Recursion

Splits strings recursively, validating if segments form valid palindromes before partitioning deep subproblems.

  • LeetCode 131: Palindrome Partitioning
def partition(s):
    res = []
    def backtrack(start, path):
        if start == len(s):
            res.append(path[:]); return
        for end in range(start + 1, len(s) + 1):
            sub = s[start:end]
            if sub == sub[::-1]:
                path.append(sub)
                backtrack(end, path)
                path.pop()
    backtrack(0, [])
    return res
Pruning / State Tracking Recursion

Prunes recursion branches early using mathematical checks or pre-sorted states.

  • LeetCode 51: N-Queens
  • LeetCode 37: Sudoku Solver
def is_safe(r, c, board):
    # validates row, column, and diagonal constraints to prune search early
    return True
Merge sort pattern Recursion

Splits lists recursively, sorting fragments and stiching them back together.

  • LeetCode 912: Sort an Array (Merge Sort)
def merge_sort(arr):
    if len(arr) <= 1: return arr
    mid = len(arr) // 2
    l = merge_sort(arr[:mid])
    r = merge_sort(arr[mid:])
    return merge(l, r)
Quick select (Kth largest) Recursion

Quickselect splits array bounds around pivots to locate elements in O(N) average time.

  • LeetCode 215: Kth Largest Element in an Array
def quickselect(arr, k, l, r):
    # partitions around pivot indices to narrow search bounds
    pass
Count inversions Recursion

Counts elements occurring out of order by tracking overlapping bounds inside merge sort checks.

  • GeeksforGeeks: Count Inversions
def merge_count(arr, l, r):
    # sums splits during sorted merges
    pass
Top K/ Kth Element/ k closest points Heap

Retains K target elements by maintaining a size K priority min-heap.

  • LeetCode 347: Top K Frequent
  • LeetCode 973: K Closest Points
import heapq
def top_k_frequent(nums, k):
    counts = Counter(nums)
    heap = []
    for num, count in counts.items():
        heapq.heappush(heap, (count, num))
        if len(heap) > k: heapq.heappop(heap)
    return [x[1] for x in heap]
Task scheduler Heap

Schedules highly frequent elements using priority max-heaps combined with cooling queues.

  • LeetCode 621: Task Scheduler
import heapq
from collections import Counter, deque
def task_scheduler(tasks, n):
    counts = Counter(tasks)
    heap = [-c for c in counts.values()]
    heapq.heapify(heap)
    q = deque()
    time = 0
    while heap or q:
        time += 1
        if heap:
            cnt = heapq.heappop(heap) + 1
            if cnt != 0: q.append((cnt, time + n))
        if q and q[0][1] == time:
            heapq.heappush(heap, q.popleft()[0])
    return time
Meeting rooms Heap

Maintains meeting end times inside min-heaps to determine minimum overlap platforms.

  • LeetCode 253: Meeting Rooms II
import heapq
def min_meeting_rooms(intervals):
    if not intervals: return 0
    intervals.sort(key=lambda x: x[0])
    heap = [intervals[0][1]]
    for start, end in intervals[1:]:
        if heap[0] <= start: heapq.heappop(heap)
        heapq.heappush(heap, end)
    return len(heap)
Reorganize string Heap

Reorganizes character strings using priority heaps to always place the most frequent remaining characters.

  • LeetCode 767: Reorganize String
import heapq
def reorganize_string(s):
    counts = Counter(s)
    heap = [(-cnt, char) for char, cnt in counts.items()]
    heapq.heapify(heap)
    prev_cnt, prev_char = 0, ""
    res = []
    while heap:
        cnt, char = heapq.heappop(heap)
        res.append(char)
        if prev_cnt < 0: heapq.heappush(heap, (prev_cnt, prev_char))
        prev_cnt, prev_char = cnt + 1, char
    return "".join(res) if len(res) == len(s) else ""
Huffman encoding Heap

Stitches nodes recursively by picking the two lowest weight nodes in priority heaps to build encoding trees.

  • GeeksforGeeks: Huffman Coding
def build_huffman(freqs):
    # heaps lowest nodes iteratively to construct trees
    pass
K-way Merge Heap

Merges sorted streams by maintaining a min-heap populated with the current heads of each stream.

  • LeetCode 23: Merge K Sorted Lists
  • LeetCode 378: Kth Smallest in Sorted Matrix
import heapq
def merge_k_lists(lists):
    heap = []
    for i, lst in enumerate(lists):
        if lst: heapq.heappush(heap, (lst.val, i, lst))
    dummy = ListNode()
    curr = dummy
    while heap:
        val, idx, node = heapq.heappop(heap)
        curr.next = ListNode(val)
        curr = curr.next
        if node.next:
            heapq.heappush(heap, (node.next.val, idx, node.next))
    return dummy.next
BFS Graphs

Explores vertices level-by-level using a FIFO queue, finding shortest paths on unweighted graphs.

  • LeetCode 200: Number of Islands (BFS)
from collections import deque
def bfs_graph(start, adj):
    visited = {start}
    q = deque([start])
    while q:
        u = q.popleft()
        for v in adj[u]:
            if v not in visited:
                visited.add(v); q.append(v)
DFS Graphs

Explores vertices recursively along paths before backtracking, key for connectivity checks.

  • LeetCode 200: Number of Islands (DFS)
def dfs_graph(u, adj, visited):
    visited.add(u)
    for v in adj[u]:
        if v not in visited:
            dfs_graph(v, adj, visited)
Directed Graphs

Checks cycles using recursion stack sets or coloring (unvisited/visiting/visited) in DFS traversals.

  • LeetCode 207: Course Schedule (DFS Cycle Check)
def has_cycle_directed(crs, adj, state):
    if state[crs] == 1: return True # visiting
    if state[crs] == 2: return False # visited
    state[crs] = 1
    for pre in adj[crs]:
        if has_cycle_directed(pre, adj, state): return True
    state[crs] = 2
    return False
Undirected Graphs

Checks cycle by verifying if visited nodes are reached from paths other than direct parent routes.

  • LeetCode 684: Redundant Connection
def has_cycle_undirected(u, parent, adj, visited):
    visited.add(u)
    for v in adj[u]:
        if v == parent: continue
        if v in visited: return True
        if has_cycle_undirected(v, u, adj, visited): return True
    return False
Topological Sort (BFS / DFS) Graphs

Linear ordering of Directed Acyclic Graph vertices such that for edge U-V, node U occurs before V.

  • LeetCode 210: Course Schedule II
def topo_sort(n, adj):
    visited = [0]*n; res = []
    def dfs(u):
        visited[u] = 1
        for v in adj[u]:
            if visited[v] == 1: return False
            if visited[v] == 0 and not dfs(v): return False
        visited[u] = 2; res.append(u); return True
    for i in range(n):
        if visited[i] == 0 and not dfs(i): return []
    return res[::-1]
Kahn's algorithm (BFS in-degree) Graphs

Uses in-degree counts and queues to extract topological ordering from directed graphs.

  • LeetCode 207: Course Schedule (Kahn version)
def kahns(n, adj):
    indegree = [0]*n
    for u in range(n):
        for v in adj[u]: indegree[v] += 1
    q = deque([i for i in range(n) if indegree[i] == 0])
    order = []
    while q:
        u = q.popleft()
        order.append(u)
        for v in adj[u]:
            indegree[v] -= 1
            if indegree[v] == 0: q.append(v)
    return order if len(order) == n else []
DFS-based topo sort Graphs

Traverses graph recursively via DFS, pushing finished nodes to a stack/list to reverse.

  • LeetCode 210: Course Schedule II (DFS)
def dfs_topo(u, adj, visited, stack):
    visited.add(u)
    for v in adj[u]:
        if v not in visited: dfs_topo(v, adj, visited, stack)
    stack.append(u)
Dijkstra Graphs

Finds shortest paths from a source node using a Priority Queue on positive weighted graphs.

  • LeetCode 743: Network Delay Time
import heapq
def dijkstra(start, n, adj):
    dist = {i: float('inf') for i in range(1, n+1)}
    dist[start] = 0
    pq = [(0, start)]
    while pq:
        d, u = heapq.heappop(pq)
        if d > dist[u]: continue
        for v, w in adj[u]:
            if dist[u] + w < dist[v]:
                dist[v] = dist[u] + w
                heapq.heappush(pq, (dist[v], v))
    return dist
Bellman-Ford Graphs

Finds shortest paths relaxation in O(V*E) supporting negative weights and detecting cycle failures.

  • LeetCode 787: Cheapest Flights Within K Stops
def bellman_ford(start, n, edges):
    dist = [float('inf')] * n
    dist[start] = 0
    for _ in range(n - 1):
        for u, v, w in edges:
            if dist[u] != float('inf') and dist[u] + w < dist[v]:
                dist[v] = dist[u] + w
    return dist
Floyd-Warshall (all pairs) Graphs

Calculates all-pairs shortest paths using 3-nested DP matrix loops relaxed over intermediates.

  • LeetCode 1334: Cities with Smallest Neighbors
def floyd_warshall(n, edges):
    dist = [[float('inf')]*n for _ in range(n)]
    for i in range(n): dist[i][i] = 0
    for u, v, w in edges: dist[u][v] = w
    for k in range(n):
        for i in range(n):
            for j in range(n):
                dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
    return dist
Kruskal Graphs

Finds Minimum Spanning Tree by sorting edges and connecting them recursively using Union-Find.

  • LeetCode 1584: Min Cost to Connect All Points (Kruskal)
def kruskal(n, edges):
    parent = list(range(n))
    def find(i):
        if parent[i] == i: return i
        parent[i] = find(parent[i])
        return parent[i]
    edges.sort(key=lambda x: x[2])
    cost = 0
    for u, v, w in edges:
        root_u, root_v = find(u), find(v)
        if root_u != root_v:
            parent[root_u] = root_v; cost += w
    return cost
Prims Graphs

Grows Spanning Tree greedily by popping min weighted cut edges off heaps.

  • LeetCode 1584: Min Cost to Connect Points (Prim version)
import heapq
def prims(n, adj):
    visited = set()
    pq = [(0, 0)] # (weight, node)
    cost = 0
    while len(visited) < n:
        w, u = heapq.heappop(pq)
        if u in visited: continue
        visited.add(u); cost += w
        for v, weight in adj[u]:
            if v not in visited: heapq.heappush(pq, (weight, v))
    return cost
Union-Find (DSU) Detect cycle in undirected Graphs

Identifies connectivity cycles in undirected graphs efficiently using representative parenting arrays.

  • LeetCode 684: Redundant Connection
class DSU:
    def __init__(self, size):
        self.parent = list(range(size))
    def find(self, i):
        if self.parent[i] == i: return i
        self.parent[i] = self.find(self.parent[i])
        return self.parent[i]
    def union(self, i, j):
        root_i, root_j = self.find(i), self.find(j)
        if root_i == root_j: return False
        self.parent[root_i] = root_j; return True
Bipartite/ Multi-source BFS/ 0-1 BFS Graphs

Groups graphs vertices into bipartite colors or resolves dual-edge grids using specialized double ended queues.

  • LeetCode 785: Is Graph Bipartite?
  • LeetCode 542: 01 Matrix (Multi-source BFS)
def is_bipartite(graph):
    color = {}
    for node in range(len(graph)):
        if node not in color:
            q = deque([node])
            color[node] = 0
            while q:
                u = q.popleft()
                for v in graph[u]:
                    if v in color:
                        if color[v] == color[u]: return False
                    else:
                        color[v] = 1 - color[u]; q.append(v)
    return True
Insert/Search TRIE

Inserts and searches keys character-by-character in prefix tree nodes.

  • LeetCode 208: Implement Trie
class TrieNode:
    def __init__(self):
        self.children = {}
        self.is_word = False

class Trie:
    def __init__(self):
        self.root = TrieNode()
    def insert(self, word):
        node = self.root
        for c in word:
            node = node.children.setdefault(c, TrieNode())
        node.is_word = True
Prefix Match TRIE

Checks prefix boundaries to support autocomplete recommendations or suggest searches.

  • LeetCode 208: StartsWith Method
  • LeetCode 1268: Search Suggestions System
def starts_with(self, prefix):
    node = self.root
    for c in prefix:
        if c not in node.children: return False
        node = node.children[c]
    return True
Bitwise Trie TRIE

Aligns numbers as bit paths to evaluate maximum XOR splits in O(32) time.

  • LeetCode 421: Maximum XOR of Two Numbers
class BitTrieNode:
    def __init__(self):
        self.children = [None, None]
1D DYNAMIC PROGRAMMING

Tracks optimal computations iteratively in a flat 1D state array.

  • LeetCode 70: Climbing Stairs
  • LeetCode 198: House Robber
def climb_stairs(n):
    if n <= 2: return n
    dp = [0]*(n+1)
    dp[1], dp[2] = 1, 2
    for i in range(3, n+1): dp[i] = dp[i-1] + dp[i-2]
    return dp[n]
2D DYNAMIC PROGRAMMING

Evaluates multi-variable decisions in 2D array states.

  • LeetCode 62: Unique Paths
  • LeetCode 1143: Longest Common Subsequence
def unique_paths(m, n):
    dp = [[1]*n for _ in range(m)]
    for r in range(1, m):
        for c in range(1, n):
            dp[r][c] = dp[r-1][c] + dp[r][c-1]
    return dp[m-1][n-1]
Linear DP DYNAMIC PROGRAMMING

State transition relies on linear indices (e.g. DP[i] = DP[i-1] + DP[i-2]).

  • LeetCode 198: House Robber
  • LeetCode 91: Decode Ways
def rob(nums):
    if not nums: return 0
    dp = [0]*(len(nums)+1)
    dp[1] = nums[0]
    for i in range(2, len(nums)+1):
        dp[i] = max(dp[i-1], dp[i-2] + nums[i-1])
    return dp[-1]
Grid DP DYNAMIC PROGRAMMING

Transitions propagate along matrix directions (e.g. DP[r][c] = grid[r][c] + min(DP[r-1][c], DP[r][c-1])).

  • LeetCode 64: Minimum Path Sum
  • LeetCode 120: Triangle
def min_path_sum(grid):
    R, C = len(grid), len(grid[0])
    for r in range(R):
        for c in range(C):
            if r == 0 and c == 0: continue
            elif r == 0: grid[r][c] += grid[r][c-1]
            elif c == 0: grid[r][c] += grid[r-1][c]
            else: grid[r][c] += min(grid[r-1][c], grid[r][c-1])
    return grid[-1][-1]
Decision DP DYNAMIC PROGRAMMING

Selects optimal transitions from a set of choices at each index (e.g. holding or selling stocks).

  • LeetCode 309: Best Time to Buy and Sell Stock with Cooldown
def max_profit(prices):
    if not prices: return 0
    hold, sold, rest = -prices[0], 0, 0
    for p in prices[1:]:
        prev_sold = sold
        sold = hold + p
        hold = max(hold, rest - p)
        rest = max(rest, prev_sold)
    return max(sold, rest)
Knapsack DYNAMIC PROGRAMMING

Decides item subsets to include/exclude to maximize value within capacity weights.

  • LeetCode 416: Partition Equal Subset Sum
  • LeetCode 322: Coin Change
def coin_change(coins, amount):
    dp = [amount + 1] * (amount + 1)
    dp[0] = 0
    for i in range(1, amount + 1):
        for c in coins:
            if i >= c: dp[i] = min(dp[i], dp[i-c] + 1)
    return dp[amount] if dp[amount] <= amount else -1
Sequence DP DYNAMIC PROGRAMMING

Evaluates matching subsequences or alignments between string intervals.

  • LeetCode 1143: LCS
  • LeetCode 300: LIS
def lcs(s1, s2):
    m, n = len(s1), len(s2)
    dp = [[0]*(n+1) for _ in range(m+1)]
    for i in range(1, m+1):
        for j in range(1, n+1):
            if s1[i-1] == s2[j-1]: dp[i][j] = dp[i-1][j-1] + 1
            else: dp[i][j] = max(dp[i-1][j], dp[i][j-1])
    return dp[m][n]
Partition DP DYNAMIC PROGRAMMING

Splits elements dynamically into separate partition groups to locate optimal configurations.

  • LeetCode 1043: Partition Array for Maximum Sum
def max_sum_partition(arr, k):
    n = len(arr)
    dp = [0]*(n+1)
    for i in range(1, n+1):
        curr_max = 0
        for j in range(1, min(i, k)+1):
            curr_max = max(curr_max, arr[i-j])
            dp[i] = max(dp[i], dp[i-j] + curr_max * j)
    return dp[n]
Interval DP DYNAMIC PROGRAMMING

Computes subproblem intervals recursively, branching over internal pivot boundaries.

  • LeetCode 312: Burst Balloons
def burst_balloons(nums):
    # burst window intervals L iteratively from pivot bounds
    pass
Bitmask DP DYNAMIC PROGRAMMING

Leverages numeric integer bit representations to represent item selection combinations.

  • LeetCode 526: Beautiful Arrangement
def solve_mask(idx, mask, n, memo={}):
    if idx > n: return 1
    if (idx, mask) in memo: return memo[(idx, mask)]
    ans = 0
    for val in range(1, n+1):
        if not (mask & (1 << val)):
            if val % idx == 0 or idx % val == 0:
                ans += solve_mask(idx+1, mask | (1<<val), n, memo)
    memo[(idx, mask)] = ans; return ans
Digit DP DYNAMIC PROGRAMMING

Counts decimal digit strings recursively matching constraints bounded by numeric values.

  • LeetCode 233: Number of Digit One
def solve_digit(idx, count, is_limit):
    # recursion sweeps over digit limitations
    pass
DP on Trees DYNAMIC PROGRAMMING

Solves recursive node decisions bottom-up, keeping track of choice states (include/exclude) in tree nodes.

  • LeetCode 337: House Robber III
def rob_tree(root):
    def dfs(node):
        if not node: return (0, 0) # (rob, skip)
        l, r = dfs(node.left), dfs(node.right)
        rob_val = node.val + l[1] + r[1]
        skip_val = max(l) + max(r)
        return (rob_val, skip_val)
    return max(dfs(root))
Memoization DYNAMIC PROGRAMMING

Saves recursive outputs inside dictionary caches to bypass duplicate state branches (Top-down).

  • LeetCode 509: Fibonacci Memo version
def fib_memo(n, memo={}):
    if n in memo: return memo[n]
    if n <= 1: return n
    memo[n] = fib_memo(n-1) + fib_memo(n-2)
    return memo[n]
Tabulation DYNAMIC PROGRAMMING

Builds optimal parameters iteratively bottom-up in arrays (Tabulation).

  • LeetCode 70: Climbing Stairs Tabulation
def climb_tab(n):
    dp = [0, 1, 2] # base instances
    for i in range(3, n+1): dp.append(dp[-1] + dp[-2])
    return dp[n]
Activity Selection GREEDY

Sorts intervals by their end times, always selecting the earliest ending activity to maximize schedule count.

  • LeetCode 435: Non-overlapping Intervals
def activity_select(intervals):
    intervals.sort(key=lambda x: x[1])
    cnt = 1; end = intervals[0][1]
    for s, e in intervals[1:]:
        if s >= end: cnt += 1; end = e
    return cnt
Non-overlapping Intervals GREEDY

Sorts intervals by end times to locate and remove overlapping boundaries.

  • LeetCode 435: Non-overlapping Intervals (Removals version)
def erase_overlap(intervals):
    if not intervals: return 0
    intervals.sort(key=lambda x: x[1])
    end = intervals[0][1]; del_cnt = 0
    for s, e in intervals[1:]:
        if s < end: del_cnt += 1
        else: end = e
    return del_cnt
Minimum Removals GREEDY

Greedily strips overlapping subsegments by comparing current boundaries against maximum overlapping limits.

  • LeetCode 452: Minimum Arrows to Burst Balloons
def find_min_arrows(points):
    if not points: return 0
    points.sort(key=lambda x: x[1])
    arrows = 1; end = points[0][1]
    for s, e in points[1:]:
        if s > end: arrows += 1; end = e
    return arrows
Deadline Based Scheduling GREEDY

Schedules elements on latest possible empty slots matching deadlines to avoid profit gaps.

  • GeeksforGeeks: Job Sequencing Problem
def job_sequence(jobs, t):
    # jobs: [(id, deadline, profit)] sorted by profit desc
    pass
Profit Based Selection GREEDY

Picks high profit elements dynamically, resolving deadline overlap gaps using heaps.

  • LeetCode 630: Course Schedule III
import heapq
def schedule_courses(courses):
    courses.sort(key=lambda x: x[1])
    heap = []; time = 0
    for duration, end in courses:
        time += duration
        heapq.heappush(heap, -duration)
        if time > end: time += heapq.heappop(heap)
    return len(heap)
Minimum Platforms / Rooms GREEDY

Tracks arrivals and departures systematically to count maximum active overlapping intervals.

  • LeetCode 253: Meeting Rooms II
  • GeeksforGeeks: Minimum Platforms
def find_platforms(arr, dep):
    arr.sort(); dep.sort()
    p_needed = max_p = 1
    i = 1; j = 0
    while i < len(arr) and j < len(dep):
        if arr[i] <= dep[j]:
            p_needed += 1; i += 1
        else:
            p_needed -= 1; j += 1
        max_p = max(max_p, p_needed)
    return max_p
Meeting Rooms GREEDY

Validates meeting compatibility by sorting start times and checking for overlaps.

  • LeetCode 252: Meeting Rooms
def can_attend(intervals):
    intervals.sort()
    for i in range(len(intervals)-1):
        if intervals[i][1] > intervals[i+1][0]: return False
    return True
Jump Game Pattern GREEDY

Greedily tracks the furthest index reachable at each position to solve traversal availability.

  • LeetCode 55: Jump Game
  • LeetCode 45: Jump Game II
def can_jump(nums):
    max_reach = 0
    for i, jump in enumerate(nums):
        if i > max_reach: return False
        max_reach = max(max_reach, i + jump)
    return True
Huffman / Merge Cost GREEDY

Greedily connects two shortest elements using heaps to minimize total merge cost.

  • GeeksforGeeks: Minimum Cost to Connect Ropes
import heapq
def min_rope_cost(ropes):
    heapq.heapify(ropes)
    cost = 0
    while len(ropes) > 1:
        first, second = heapq.heappop(ropes), heapq.heappop(ropes)
        comb = first + second; cost += comb
        heapq.heappush(ropes, comb)
    return cost
XOR Pattern BIT MANIPULATION

Uses XOR self-inverse logic (X ^ X = 0) to cancel out duplicates.

  • LeetCode 136: Single Number
def single_number(nums):
    xor = 0
    for x in nums: xor ^= x
    return xor
Bit Masking BIT MANIPULATION

Applies bitwise masks to set, clear, or check specific bits.

  • LeetCode 190: Reverse Bits
def reverse_bits(n):
    res = 0
    for _ in range(32):
        res = (res << 1) | (n & 1)
        n >>= 1
    return res
Subset via Bits BIT MANIPULATION

Generates power subsets by mapping bit patterns (0 to 2^N - 1) directly to elements indexes.

  • LeetCode 78: Subsets using bits
def subsets_bits(nums):
    n = len(nums)
    res = []
    for mask in range(1 << n):
        subset = []
        for i in range(n):
            if mask & (1 << i): subset.append(nums[i])
        res.append(subset)
    return res
Bit Checks BIT MANIPULATION

Uses bitwise checks (e.g. n & (n - 1)) to validate number properties in O(1) time.

  • LeetCode 231: Power of Two
  • LeetCode 191: Number of 1 Bits
def is_power_of_two(n):
    return n > 0 and (n & (n - 1)) == 0
Prefix XOR BIT MANIPULATION

Precomputes prefix XOR parameters to support constant range XOR sweeps.

  • LeetCode 1310: XOR Queries
def prefix_xor(arr):
    prefix = [0]
    for x in arr: prefix.append(prefix[-1] ^ x)
    return prefix
Bubble Sort Sorting Algorithms

Repeatedly swaps adjacent elements if they are out of order. Ideal for educational analysis. O(N^2) complexity.

  • GeeksforGeeks: Bubble Sort
def bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        swapped = False
        for j in range(0, n - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
                swapped = True
        if not swapped: break
Selection Sort Sorting Algorithms

Iteratively finds the minimum element in unsorted sections and places it at the starting sorted index. O(N^2) complexity.

  • GeeksforGeeks: Selection Sort
def selection_sort(arr):
    n = len(arr)
    for i in range(n):
        min_idx = i
        for j in range(i + 1, n):
            if arr[j] < arr[min_idx]: min_idx = j
        arr[i], arr[min_idx] = arr[min_idx], arr[i]
Insertion Sort Sorting Algorithms

Inserts unsorted elements into their correct position in a growing sorted section. O(N^2) complexity.

  • GeeksforGeeks: Insertion Sort
def insertion_sort(arr):
    for i in range(1, len(arr)):
        key = arr[i]
        j = i - 1
        while j >= 0 and arr[j] > key:
            arr[j + 1] = arr[j]
            j -= 1
        arr[j + 1] = key
Merge Sort Sorting Algorithms

Guarantees stable O(N log N) sorting using a divide-and-conquer strategy to split and merge sub-arrays.

  • LeetCode 912: Sort an Array (Merge Sort)
def merge_sort(arr):
    if len(arr) <= 1: return arr
    mid = len(arr) // 2
    l = merge_sort(arr[:mid])
    r = merge_sort(arr[mid:])
    # merge logic...
    pass
Quick Sort Sorting Algorithms

Sorts in-place in O(N log N) average time by partitioning smaller/larger values around a pivot index.

  • LeetCode 912: Sort an Array (Quick Sort)
def quicksort(arr):
    if len(arr) <= 1: return arr
    pivot = arr[len(arr) // 2]
    l = [x for x in arr if x < pivot]
    m = [x for x in arr if x == pivot]
    r = [x for x in arr if x > pivot]
    return quicksort(l) + m + quicksort(r)
Heap Sort Sorting Algorithms

Sorts elements in O(N log N) in-place time by loading items into a binary heap and pulling root elements.

  • LeetCode 912: Heap Sort version
import heapq
def heap_sort(arr):
    heapq.heapify(arr)
    return [heapq.heappop(arr) for _ in range(len(arr))]
Counting Sort Sorting Algorithms

Achieves linear O(N + K) sorting by counting occurrences of each unique value, suitable for small positive integer bounds.

  • LeetCode 75: Sort Colors (Counting)
def counting_sort(arr):
    counts = [0] * (max(arr) + 1)
    for x in arr: counts[x] += 1
    res = []
    for val, cnt in enumerate(counts): res.extend([val]*cnt)
    return res
Radix Sort Sorting Algorithms

Sorts integers digit-by-digit from LSB to MSB in O(D * (N + B)) time using counting sort as a stable base.

  • LeetCode 164: Maximum Gap (Radix Sort)
def radix_sort(arr):
    # stable sorting digit-by-digit from least to most significant
    pass
Bucket Sort Sorting Algorithms

Distributes elements uniformly into buckets, sorts them individually, and aggregates them back in linear average time.

  • LeetCode 347: Bucket Sort version
def bucket_sort(arr):
    # splits elements evenly across list buckets
    pass
Range Query RANGE STRUCTURES

Executes range sum or range minimum queries inside segment trees in O(log N) time.

  • LeetCode 307: Range Sum Query - Mutable
class SegmentTree:
    def __init__(self, arr):
        self.n = len(arr)
        self.tree = [0]*(4*self.n)
        self.build(arr, 0, 0, self.n - 1)
    def build(self, arr, idx, l, r):
        if l == r:
            self.tree[idx] = arr[l]; return
        mid = (l + r) // 2
        self.build(arr, 2*idx+1, l, mid)
        self.build(arr, 2*idx+2, mid+1, r)
        self.tree[idx] = self.tree[2*idx+1] + self.tree[2*idx+2]
Lazy Propagation RANGE STRUCTURES

Optimizes range updates to O(log N) inside segment trees by deferring updates until queried.

  • Codeforces: Range Updates Lazy Propagation
def update_range(node, l, r, ql, qr, val):
    # propagates lazy additions down during traversal checks
    pass
Prefix Query RANGE STRUCTURES

Maintains prefix sums inside flat index arrays, updating and querying sums in O(log N) using LSB index shifts.

  • LeetCode 307: Range Sum (BIT version)
  • LeetCode 315: Count Smaller Numbers After Self
class BIT:
    def __init__(self, size):
        self.tree = [0]*(size + 1)
    def update(self, idx, val):
        while idx < len(self.tree):
            self.tree[idx] += val
            idx += idx & (-idx)
    def query(self, idx):
        s = 0
        while idx > 0:
            s += self.tree[idx]
            idx -= idx & (-idx)
        return s

Based on the DSA RM project by Jakkula Veerababu / THFLSH9Z. Code examples are learning templates; some are intentionally incomplete. No hiring outcome or company endorsement is implied.