SuperAPI AI Directory

python-algorithm-cookbook

Coding & development

View repository

Updated 10-15 20:07

About this skill

Common Algorithm Patterns

Sliding Window (Two Pointers)

# Pattern: Longest Substring Without Repeating Characters
def length_of_longest_substring(s: str) -> int:
    """Find length of longest substring without repeating characters.

    Sliding window technique with hash map to track character positions.
    Time: O(n), Space: O(min(n, alphabet_size))

    Example: "abcabcbb" -> 3 (substring "abc")
    """
    if not s:
        return 0
# Track last seen index of each character
char_index: dict[str, int] = {}
max_length = 0
left = 0  # Left pointer of sliding window

for right, char in enumerate(s):
    # If character seen AND it's within current window
    if char in char_index and char_index[char] >= left:
        # Move left pointer past the previous occurrence
        # This maintains "no repeating chars" invariant
        left = char_index[char] + 1

    # Update character's latest position
    char_index[char] = right

    # Update max length seen so far
    # Current window size is (right - left + 1)
    max_length = max(max_length, right - left + 1)

return max_length
Sliding Window Key Principles: 1. Two pointers: left (start) and right (end) define window 2. Expand window by incrementing right pointer 3. Contract window by incrementing left when constraint violated 4. Track window state with hash map, set, or counter 5. Update result during expansion or contraction Common uses: substring/subarray with constraints (unique chars, max sum, min length)

## BFS Tree Traversal (Level Order)

```python
# Pattern: Binary Tree Level Order Traversal (BFS)
from collections import deque
from typing import Optional

class TreeNode:
    def __init__(self, val: int = 0, left: Optional['TreeNode'] = None, right: Optional['TreeNode'] = None):
        self.val = val
        self.left = left
        self.right = right

def level_order_traversal(root: Optional[TreeNode]) -> list[list[int]]:
    """Perform BFS level-order traversal of binary tree.

    Returns list of lists where each inner list contains node values at that level.
    Time: O(n), Space: O(w) where w is max width of tree

    Example:
        Input:     3
                  / \
                 9  20
                   /  \
                  15   7
        Output: [[3], [9, 20], [15, 7]]
    """
    if not root:
        return []

    result: list[list[int]] = []
    queue: deque[TreeNode] = deque([root])

    while queue:
        # CRITICAL: Capture level size BEFORE processing
        # This separates current level from next level nodes
        level_size = len(queue)
        current_level: list[int] = []

        # Process exactly level_size nodes (all nodes at current level)
        for _ in range(level_size):
            node = queue.popleft()  # O(1) with deque
            current_level.append(node.val)

            # Add children for next level processing
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)

        result.append(current_level)

    return result

# BFS Key Principles:
# 1. Use collections.deque for O(1) append/popleft operations (NOT list)
# 2. Capture level_size = len(queue) before inner loop to separate levels
# 3. Process entire level before moving to next (prevents mixing levels)
# 4. Add children during current level processing
# Common uses: level order traversal, shortest path, connected components, graph exploration

Binary Search on Two Arrays

# Pattern: Median of two sorted arrays
def find_median_sorted_arrays(nums1: list[int], nums2: list[int]) -> float:
    """Find median of two sorted arrays in O(log(min(m,n))) time.

    Strategy: Binary search on smaller array to find partition point
    """
    # Ensure nums1 is smaller for optimization
    if len(nums1) > len(nums2):
        nums1, nums2 = nums2, nums1

    m, n = len(nums1), len(nums2)
    left, right = 0, m

    while left <= right:
        partition1 = (left + right) // 2
        partition2 = (m + n + 1) // 2 - partition1

        # Handle edge cases with infinity
        max_left1 = float('-inf') if partition1 == 0 else nums1[partition1 - 1]
        min_right1 = float('inf') if partition1 == m else nums1[partition1]

        max_left2 = float('-inf') if partition2 == 0 else nums2[partition2 - 1]
        min_right2 = float('inf') if partition2 == n else nums2[partition2]

        # Check if partition is valid
        if max_left1 <= min_right2 and max_left2 <= min_right1:
            # Found correct partition
            if (m + n) % 2 == 0:
                return (max(max_left1, max_left2) + min(min_right1, min_right2)) / 2
            return max(max_left1, max_left2)
        elif max_left1 > min_right2:
            right = partition1 - 1
        else:
            left = partition1 + 1

    raise ValueError("Input arrays must be sorted")

Hash Map for O(1) Lookup

# Pattern: Two sum problem
def two_sum(nums: list[int], target: int) -> tuple[int, int] | None:
    """Find indices of two numbers that sum to target.

    Time: O(n), Space: O(n)
    """
    seen: dict[int, int] = {}

    for i, num in enumerate(nums):
        complement = target - num
        if complement in seen:
            return (seen[complement], i)
        seen[num] = i

    return None

When to Use Each Pattern

  • Sliding Window: Substring/subarray with constraints (unique chars, max/min sum, fixed/variable length)
  • BFS with Deque: Tree/graph level-order traversal, shortest path, connected components
  • Binary Search on Two Arrays: Median, kth element in sorted arrays (O(log n))
  • Hash Map: O(1) lookups to convert O(n^2) nested loops to O(n) single pass