---
tags:
- devops
- l2
- flashcard-deck
- python-algorithms
---
<!-- wiki:breadcrumb:start -->
[Portal](../../../../library/portal/index.md) | **Level:** [L2: Operations](../../../../library/portal/levels.md) | **Topics:** [Python Automation](../../../../library/portal/topics.md) | **Domain:** DevOps & Tooling
<!-- wiki:breadcrumb:end -->

id	category	difficulty	tags	question	answer	source_path
python-algo/cbad80a34d45	python-algo	easy	python, algorithms, hash-set, two-pointer	Find all pairs in an array that sum to k	Use a set to track complements in O(n) time.\n\ndef two_sum_pairs(arr, k):\n    seen = set()\n    pairs = []\n    for x in arr:\n        if k - x in seen:\n            pairs.append((k - x, x))\n        seen.add(x)\n    return pairs\n\nAlternative: sort + two-pointer approach runs O(n log n) but uses O(1) extra space. The hash-set approach is preferred for interviews unless space is constrained.	interview-qa-gap-analysis
python-algo/00fa0ebde156	python-algo	easy	python, algorithms, hash-map, string	Find the first non-repeating character in a string	Use collections.Counter to count frequencies, then iterate to find the first with count 1.\n\nfrom collections import Counter\ndef first_unique(s):\n    counts = Counter(s)\n    for ch in s:\n        if counts[ch] == 1:\n            return ch\n    return None\n\nTime: O(n), Space: O(k) where k is alphabet size. Two-pass approach — first pass counts, second finds.	interview-qa-gap-analysis
python-algo/cfe950389277	python-algo	medium	python, algorithms, array, prefix	Product array — compute products of all elements except self	Build prefix and suffix product arrays, then multiply.\n\ndef product_except_self(nums):\n    n = len(nums)\n    result = [1] * n\n    prefix = 1\n    for i in range(n):\n        result[i] = prefix\n        prefix *= nums[i]\n    suffix = 1\n    for i in range(n - 1, -1, -1):\n        result[i] *= suffix\n        suffix *= nums[i]\n    return result\n\nO(n) time, O(1) extra space (output array not counted). No division needed — handles zeros correctly.	interview-qa-gap-analysis
python-algo/80ca56343568	python-algo	medium	python, algorithms, linked-list, two-pointer	Find the middle element of a linked list in one pass	Use slow/fast pointer technique (Floyd's tortoise and hare).\n\ndef find_middle(head):\n    slow = fast = head\n    while fast and fast.next:\n        slow = slow.next\n        fast = fast.next.next\n    return slow\n\nWhen fast reaches the end, slow is at the middle. O(n) time, O(1) space. For even-length lists, this returns the second middle node.	interview-qa-gap-analysis
python-algo/fd8df7eef84e	python-algo	medium	python, algorithms, linked-list, two-pointer	Detect a cycle in a linked list	Floyd's cycle detection: use slow (1 step) and fast (2 step) pointers.\n\ndef has_cycle(head):\n    slow = fast = head\n    while fast and fast.next:\n        slow = slow.next\n        fast = fast.next.next\n        if slow is fast:\n            return True\n    return False\n\nTo find the cycle start: when slow == fast, reset one pointer to head and advance both by 1 — they meet at the cycle entry. O(n) time, O(1) space.	interview-qa-gap-analysis
python-algo/60278b9a309c	python-algo	medium	python, algorithms, graph, bfs, dfs	Implement DFS and BFS for a graph	DFS uses a stack (or recursion), BFS uses a queue.\n\nfrom collections import deque\n\ndef bfs(graph, start):\n    visited, queue = set(), deque([start])\n    visited.add(start)\n    while queue:\n        node = queue.popleft()\n        for neighbor in graph[node]:\n            if neighbor not in visited:\n                visited.add(neighbor)\n                queue.append(neighbor)\n    return visited\n\ndef dfs(graph, start, visited=None):\n    if visited is None: visited = set()\n    visited.add(start)\n    for neighbor in graph[start]:\n        if neighbor not in visited:\n            dfs(graph, neighbor, visited)\n    return visited\n\nBFS finds shortest path in unweighted graphs. DFS is better for detecting cycles and topological sorting.	interview-qa-gap-analysis
python-algo/79b461f2a595	python-algo	hard	python, algorithms, sorting, divide-and-conquer	Implement QuickSort	Divide-and-conquer: pick a pivot, partition, recurse.\n\ndef quicksort(arr):\n    if len(arr) <= 1:\n        return arr\n    pivot = arr[len(arr) // 2]\n    left = [x for x in arr if x < pivot]\n    mid = [x for x in arr if x == pivot]\n    right = [x for x in arr if x > pivot]\n    return quicksort(left) + mid + quicksort(right)\n\nAverage O(n log n), worst O(n^2) with bad pivot choice. In-place variant uses Lomuto or Hoare partitioning. Python's built-in sorted() uses Timsort (O(n log n) guaranteed).	interview-qa-gap-analysis
python-algo/a81d84835f3c	python-algo	hard	python, algorithms, trie, data-structure	Implement a Trie (prefix tree)	A tree where each node represents a character prefix.\n\nclass TrieNode:\n    def __init__(self):\n        self.children = {}\n        self.is_end = False\n\nclass Trie:\n    def __init__(self):\n        self.root = TrieNode()\n\n    def insert(self, word):\n        node = self.root\n        for ch in word:\n            if ch not in node.children:\n                node.children[ch] = TrieNode()\n            node = node.children[ch]\n        node.is_end = True\n\n    def search(self, word):\n        node = self._find(word)\n        return node is not None and node.is_end\n\n    def starts_with(self, prefix):\n        return self._find(prefix) is not None\n\nUsed for autocomplete, spell-check, IP routing. O(m) per operation where m is word length.	interview-qa-gap-analysis
python-algo/735bf864eec4	python-algo	medium	python, algorithms, string, hash-map	Check anagram removal count for two strings	Count character frequencies and sum absolute differences.\n\nfrom collections import Counter\ndef anagram_removals(s1, s2):\n    c1, c2 = Counter(s1), Counter(s2)\n    return sum((c1 - c2).values()) + sum((c2 - c1).values())\n\nThis gives the total characters to remove from both strings to make them anagrams. Counter subtraction only keeps positive counts, so we sum both directions. O(n + m) time.	interview-qa-gap-analysis
python-algo/49a22cba228e	python-algo	medium	python, algorithms, prefix-sum, hash-set	Determine if a zero-sum subarray exists	Track prefix sums — if a prefix sum repeats, a zero-sum subarray exists.\n\ndef has_zero_sum_subarray(arr):\n    prefix_sums = set([0])\n    running = 0\n    for x in arr:\n        running += x\n        if running in prefix_sums:\n            return True\n        prefix_sums.add(running)\n    return False\n\nKey insight: if prefix_sum[j] == prefix_sum[i], then sum(arr[i+1:j+1]) == 0. Include 0 in initial set to catch subarrays starting at index 0. O(n) time and space.	interview-qa-gap-analysis
python-algo/1c28dcb2155d	python-algo	medium	python, algorithms, sorting, greedy	Generate the largest number from a list of integers	Custom sort: compare concatenated strings.\n\nfrom functools import cmp_to_key\ndef largest_number(nums):\n    strs = list(map(str, nums))\n    strs.sort(key=cmp_to_key(lambda a, b: (1 if a+b < b+a else -1 if a+b > b+a else 0)))\n    result = ''.join(strs)\n    return '0' if result[0] == '0' else result\n\nCompare '9'+'34' vs '34'+'9' -> '934' > '349' so 9 comes first. Edge case: all zeros -> return '0'. O(n log n) time.	interview-qa-gap-analysis
python-algo/190d1d976248	python-algo	medium	python, algorithms, stack, monotonic	Calculate the stock span problem	Use a monotonic decreasing stack to find previous greater elements.\n\ndef stock_span(prices):\n    spans = []\n    stack = []  # (price, index)\n    for i, price in enumerate(prices):\n        while stack and stack[-1][0] <= price:\n            stack.pop()\n        span = i + 1 if not stack else i - stack[-1][1]\n        spans.append(span)\n        stack.append((price, i))\n    return spans\n\nThe span for day i is the number of consecutive days before it (including itself) where price was <= price[i]. Classic monotonic stack pattern. O(n) amortized.	interview-qa-gap-analysis
python-algo/2c12deebea7d	python-algo	medium	python, algorithms, linked-list, data-structure	Implement a linked list with insert, find, delete	class Node:\n    def __init__(self, val, nxt=None):\n        self.val = val\n        self.next = nxt\n\nclass LinkedList:\n    def __init__(self):\n        self.head = None\n\n    def insert(self, val):\n        self.head = Node(val, self.head)\n\n    def find(self, val):\n        curr = self.head\n        while curr:\n            if curr.val == val: return curr\n            curr = curr.next\n        return None\n\n    def delete(self, val):\n        if not self.head: return\n        if self.head.val == val:\n            self.head = self.head.next; return\n        curr = self.head\n        while curr.next:\n            if curr.next.val == val:\n                curr.next = curr.next.next; return\n            curr = curr.next\n\nInsert: O(1) at head. Find/Delete: O(n). Use a sentinel/dummy head node to simplify edge cases.	interview-qa-gap-analysis
python-algo/438a53129d2d	python-algo	easy	python, algorithms, string	Reverse words in a sentence	Split, reverse, rejoin.\n\ndef reverse_words(s):\n    return ' '.join(s.split()[::-1])\n\nsplit() without args handles multiple spaces. For in-place reversal (interview follow-up): reverse entire string, then reverse each word. Python strings are immutable, so true in-place requires a list of chars.	interview-qa-gap-analysis
python-algo/cfb8623761f9	python-algo	medium	python, algorithms, recursion, backtracking	Generate all permutations of a string	Use backtracking or itertools.permutations.\n\ndef permutations(s):\n    if len(s) <= 1:\n        return [s]\n    result = []\n    for i, ch in enumerate(s):\n        rest = s[:i] + s[i+1:]\n        for perm in permutations(rest):\n            result.append(ch + perm)\n    return result\n\nOr simply: from itertools import permutations as p; list(p('abc'))\n\nTime: O(n! * n). For deduplication with repeated chars, use a set or sort + skip approach.	interview-qa-gap-analysis
python-algo/f7079dd1e359	python-algo	medium	python, algorithms, two-pointer, array	Two-pointer technique for sorted array problems	Two pointers converging from both ends of a sorted array.\n\ndef two_sum_sorted(arr, target):\n    left, right = 0, len(arr) - 1\n    while left < right:\n        s = arr[left] + arr[right]\n        if s == target:\n            return (left, right)\n        elif s < target:\n            left += 1\n        else:\n            right -= 1\n    return None\n\nO(n) time, O(1) space. Works because the array is sorted. Also used for: container with most water, remove duplicates, three-sum (fix one + two-pointer on rest).	interview-qa-gap-analysis
python-algo/055d28025060	python-algo	easy	python, algorithms, binary-search, divide-and-conquer	Implement binary search	Halve the search space each iteration.\n\ndef binary_search(arr, target):\n    lo, hi = 0, len(arr) - 1\n    while lo <= hi:\n        mid = (lo + hi) // 2\n        if arr[mid] == target:\n            return mid\n        elif arr[mid] < target:\n            lo = mid + 1\n        else:\n            hi = mid - 1\n    return -1\n\nO(log n) time, O(1) space. Use bisect module in production: bisect.bisect_left(arr, target).	interview-qa-gap-analysis
python-algo/41d0d44874ce	python-algo	easy	python, algorithms, merge, two-pointer	Merge two sorted arrays	Two-pointer merge in O(n + m) time.\n\ndef merge_sorted(a, b):\n    result = []\n    i = j = 0\n    while i < len(a) and j < len(b):\n        if a[i] <= b[j]:\n            result.append(a[i]); i += 1\n        else:\n            result.append(b[j]); j += 1\n    result.extend(a[i:])\n    result.extend(b[j:])\n    return result\n\nThis is the merge step of merge sort. O(n + m) time and space. In Python, heapq.merge(a, b) does this lazily.	interview-qa-gap-analysis
python-algo/05e7107353f4	python-algo	easy	python, algorithms, string, two-pointer	Detect palindrome	Compare string to its reverse, or use two pointers.\n\ndef is_palindrome(s):\n    return s == s[::-1]\n\n# Two-pointer (better for follow-ups):\ndef is_palindrome_tp(s):\n    left, right = 0, len(s) - 1\n    while left < right:\n        if s[left] != s[right]:\n            return False\n        left += 1; right -= 1\n    return True\n\nFor alphanumeric-only: filter with isalnum() and lower() first. Extends to 'valid palindrome II' (remove at most one char).	interview-qa-gap-analysis
python-algo/f90d36cc0ddb	python-algo	hard	python, algorithms, deque, sliding-window	Sliding window maximum	Use a monotonic deque to track max in O(n).\n\nfrom collections import deque\ndef max_sliding_window(nums, k):\n    dq = deque()  # indices of useful elements\n    result = []\n    for i, num in enumerate(nums):\n        while dq and dq[0] < i - k + 1:\n            dq.popleft()\n        while dq and nums[dq[-1]] <= num:\n            dq.pop()\n        dq.append(i)\n        if i >= k - 1:\n            result.append(nums[dq[0]])\n    return result\n\nThe deque stores indices in decreasing order of values. Front is always the max for the current window. O(n) total.	interview-qa-gap-analysis

<!-- wiki:related:start -->
---

## Wiki Navigation

### Prerequisites

- Python Flashcards *(CLI)* (flashcard_deck, L1)

### Related Content

- Perl Flashcards *(CLI)* (flashcard_deck, L1) — Python Automation
- [Python Async & Concurrency](../../../../library/topics/python-async-concurrency/index.md) (Topic Pack, L2) — Python Automation
- Python Concepts Flashcards *(CLI)* (flashcard_deck, L0) — Python Automation
- [Python Debugging](../../../../library/topics/python-debugging/index.md) (Topic Pack, L1) — Python Automation
- [Python Drills](../../../../library/drills/python_drills.md) (Drill, L0) — Python Automation
- Python Exercises (Quest Ladder) *(CLI)* (Exercise Set, L0) — Python Automation
- Python Flashcards *(CLI)* (flashcard_deck, L1) — Python Automation
- Python OOP Flashcards *(CLI)* (flashcard_deck, L2) — Python Automation
- [Python Packaging](../../../../library/topics/python-packaging/index.md) (Topic Pack, L2) — Python Automation
- [Python for Infrastructure](../../../../library/topics/python-infra/index.md) (Topic Pack, L1) — Python Automation

<!-- wiki:related:end -->
