Linear Scans (3)

1
def find_max(arr):
    mx = arr[0]
    for x in arr:
        if x > mx:
            mx = x
    return mx
2
def sum_and_product(arr):
    total = 0
    for x in arr:
        total += x
    product = 1
    for x in arr:
        product *= x
    return total, product
3
def count_pairs(arr, target):
    count = 0
    seen = set()
    for x in arr:
        if target - x in seen:
            count += 1
        seen.add(x)
    return count

Nested Loops (4)

4
def all_pairs(arr):
    pairs = []
    n = len(arr)
    for i in range(n):
        for j in range(n):
            pairs.append((arr[i], arr[j]))
    return pairs
5
def print_upper_triangle(n):
    for i in range(n):
        for j in range(i, n):
            print(i, j)
6
def process(a, b):
    for x in a:
        print(x)
    for y in b:
        print(y)
7
def nested_different(a, b):
    for x in a:
        for y in b:
            print(x, y)

Logarithmic (4)

8
def binary_search(arr, target):
    lo, hi = 0, len(arr) - 1
    while lo <= hi:
        mid = (lo + hi) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            lo = mid + 1
        else:
            hi = mid - 1
    return -1
9
def count_digits(n):
    count = 0
    while n > 0:
        count += 1
        n //= 10
    return count
10
def powers_of_two(n):
    result = []
    x = 1
    while x < n:
        result.append(x)
        x *= 2
    return result
32
def power(base, exp):
    if exp == 0:
        return 1
    if exp % 2 == 0:
        half = power(base, exp // 2)
        return half * half
    return base * power(base, exp - 1)

Recursion (4)

11
def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n - 1)
12
def fib(n):
    if n <= 1:
        return n
    return fib(n - 1) + fib(n - 2)
13
def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])
    return merge(left, right)

def merge(a, b):
    result = []
    i = j = 0
    while i < len(a) and j < len(b):
        if a[i] <= b[j]:
            result.append(a[i]); i += 1
        else:
            result.append(b[j]); j += 1
    result.extend(a[i:])
    result.extend(b[j:])
    return result
14
def tree_height(node):
    if node is None:
        return 0
    left = tree_height(node.left)
    right = tree_height(node.right)
    return 1 + max(left, right)

Hash-Based (3)

15
def two_sum(nums, target):
    seen = {}
    for i, x in enumerate(nums):
        comp = target - x
        if comp in seen:
            return [seen[comp], i]
        seen[x] = i
    return []
16
def group_anagrams(words):
    groups = {}
    for w in words:
        key = tuple(sorted(w))
        groups.setdefault(key, []).append(w)
    return list(groups.values())
17
def first_unique(s):
    freq = {}
    for c in s:
        freq[c] = freq.get(c, 0) + 1
    for c in s:
        if freq[c] == 1:
            return c
    return None

Graphs & Matrices (3)

18
def bfs(graph, start):
    visited = set()
    queue = [start]
    visited.add(start)
    while queue:
        node = queue.pop(0)
        for neighbor in graph[node]:
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append(neighbor)
    return visited
19
def rotate_matrix(matrix):
    n = len(matrix)
    for i in range(n):
        for j in range(i, n):
            matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
    for row in matrix:
        row.reverse()
20
def num_islands(grid):
    if not grid:
        return 0
    rows, cols = len(grid), len(grid[0])
    count = 0

    def dfs(r, c):
        if r < 0 or r >= rows or c < 0 or c >= cols or grid[r][c] != '1':
            return
        grid[r][c] = '0'
        dfs(r+1, c); dfs(r-1, c); dfs(r, c+1); dfs(r, c-1)

    for r in range(rows):
        for c in range(cols):
            if grid[r][c] == '1':
                count += 1
                dfs(r, c)
    return count

Dynamic Programming (3)

21
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]
22
def longest_common_subseq(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]
23
def coin_change(coins, amount):
    dp = [float('inf')] * (amount + 1)
    dp[0] = 0
    for coin in coins:
        for x in range(coin, amount + 1):
            dp[x] = min(dp[x], dp[x - coin] + 1)
    return dp[amount] if dp[amount] != float('inf') else -1

Sorting-Based (2)

24
def find_duplicates(arr):
    arr.sort()
    dupes = []
    for i in range(1, len(arr)):
        if arr[i] == arr[i-1]:
            dupes.append(arr[i])
    return dupes
25
def kth_largest(arr, k):
    arr.sort(reverse=True)
    return arr[k - 1]

Traps & Gotchas (4)

26
def build_string(words):
    result = ""
    for w in words:
        result += w
    return result
27
def has_common(a, b):
    for x in a:
        if x in b:
            return True
    return False
28
def nested_with_break(arr):
    n = len(arr)
    for i in range(n):
        for j in range(n):
            if arr[j] == arr[i]:
                break
29
def remove_all(arr, val):
    while val in arr:
        arr.remove(val)
    return arr

Exponential (2)

30
def subsets(nums):
    result = [[]]
    for x in nums:
        result += [s + [x] for s in result]
    return result
31
def permutations(arr, path=[]):
    if not arr:
        return [path]
    result = []
    for i in range(len(arr)):
        result += permutations(
            arr[:i] + arr[i+1:],
            path + [arr[i]]
        )
    return result