Paths Subjects Questions Quizzes Pricing Search

Math and Geometry

Simulate carefully and let number theory do the heavy lifting

Overview Read

Math and Geometry

Most interview topics revolve around one central idea: two pointers, a monotonic stack, a graph traversal. Math and geometry problems are different. They're a grab-bag of small, self-contained puzzles that don't share a common data structure or a single reusable algorithm. What they share instead is a mindset: model the problem precisely, simulate it step by step with explicit state, and reach for a number-theory trick when a naive approach would be too slow or too imprecise. There's no shortcut around understanding each problem individually, but a handful of recurring techniques cover a surprising fraction of what shows up in interviews.

Simulation with explicit boundaries. Problems like spiral traversal are tempting to solve with a clever index formula, but that path is fragile and hard to get right under pressure. The more robust approach is to track four boundaries — top, bottom, left, right — and walk each edge of the current "ring" in turn: left-to-right across the top row, top-to-bottom down the right column, right-to-left across the bottom row, and bottom-to-top up the left column. After each edge you move the corresponding boundary inward by one, and you re-check that top <= bottom and left <= right before walking the remaining edges, since a matrix with more rows than columns (or vice versa) will exhaust one pair of boundaries before the other. The generic template looks like:

def boundary_walk(matrix):
    top, bottom = 0, len(matrix) - 1
    left, right = 0, len(matrix[0]) - 1
    result = []
    while top <= bottom and left <= right:
        for c in range(left, right + 1):
            result.append(matrix[top][c])
        top += 1
        for r in range(top, bottom + 1):
            result.append(matrix[r][right])
        right -= 1
        if top <= bottom:
            for c in range(right, left - 1, -1):
                result.append(matrix[bottom][c])
            bottom -= 1
        if left <= right:
            for r in range(bottom, top - 1, -1):
                result.append(matrix[r][left])
            left += 1
    return result

This same "shrink the boundaries" habit generalizes to other matrix-traversal problems: rotating a matrix in place, setting rows/columns to zero, or generating a spiral matrix from scratch.

Digit manipulation and overflow. Reversing the digits of an integer is a simple loop — repeatedly take n % 10 to peel off the last digit and n // 10 to drop it — but the interesting part of the problem is almost always the overflow check. If the problem specifies a signed 32-bit range (-2^31 to 2^31 - 1, i.e., roughly ±2.1 billion), you must detect when the reversed value would fall outside that range and return 0 (or raise an error) instead of silently wrapping or producing an incorrect result. In a language like Python, integers don't overflow on their own, so you have to check the bound explicitly after (or during) each digit you append.

Coordinate geometry without floating point. When comparing whether points are collinear, the naive approach computes a slope as a float (dy / dx) and compares slopes for equality. This is a trap: floating-point division introduces rounding error, and two truly-equal slopes can compare unequal after enough arithmetic. The fix is to represent a slope as a reduced fraction — the pair (dy, dx) divided by their greatest common divisor (GCD), with a consistent sign convention — and compare those integer pairs directly. For the maximum collinear points problem, this means: for each point, compute the reduced-slope to every other point, hash points by that slope, and the largest bucket (plus the point itself, plus any duplicate points) is a candidate for the best line through that point.

Recurrences. Some problems reduce to a clean recursive or iterative formula once you see the pattern. The Josephus problem — eliminate every kth person from a circle of n until one remains — has the elegant recurrence f(n, k) = (f(n-1, k) + k) % n, built bottom-up from the base case f(1, k) = 0, which finds the zero-indexed winner in O(n) time and O(1) space (O(n) if built iteratively with an array, otherwise O(n) recursion depth). Triangle numbers, and triangle-array problems like finding the minimum path sum from the top of a triangle to the bottom, are best solved bottom-up with dynamic programming: work from the last row upward, at each cell adding the smaller of the two children below it, until you collapse the whole triangle into a single answer at the top.

Complexity, in general. Most of these problems run in O(n) or O(n^2) time (spiral traversal and triangle DP are O(n^2) on their matrix; digit reversal and Josephus are O(n) or O(log n)/O(digits); collinear points is O(n^2) since it checks every pair). Space is typically O(1) to O(n), depending on whether you need auxiliary arrays or hash maps.

Common pitfalls: integer overflow when reversing digits (always check against the 32-bit bound before or as you build the result); comparing floating-point slopes instead of reduced integer fractions when checking collinearity; off-by-one errors when shrinking spiral boundaries (forgetting to re-check top <= bottom or left <= right before walking the bottom/left edges, which double-counts or skips cells on non-square matrices); and forgetting the modulo in the Josephus recurrence, which silently produces an out-of-range index.

This subject covers five problems: Spiral Traversal (boundary-tracking matrix simulation), Reverse 32-Bit Integer (digit manipulation with overflow detection), Maximum Collinear Points (slope-hashing coordinate geometry), The Josephus Problem (the classic elimination recurrence), and Triangle Numbers (bottom-up DP over a triangular array).

Pro content

Sign up free, then start a 14-day Pro trial — no card needed.

We use cookies for product analytics to improve OmniAtlas. See our Privacy Policy.