Skip to main content
ARCHITECTVI

Software Engineer

Available for work

Open to opportunities
๐ŸŽฏAlgorithms

Competitive Programming Insights

Techniques and strategies from competitive programming that translate to real-world software engineering.

Mar 10, 2024ยท10 min read
AlgorithmsProblem SolvingOptimization

Having solved 1700+ problems across Codeforces, Codechef, LightOJ, and UVA, I've noticed that the skills competitive programming sharpens are exactly the ones that separate senior engineers from junior ones in production: breaking down ambiguous problems, reasoning about worst-case complexity, and building correct solutions under pressure.

BFS/DFS: The Backbone of Half Your Production Problems

Graph traversal isn't an abstract academic exercise. Every time you compute the shortest deployment path between microservices, find transitive dependencies in a package manager, or determine if two users are connected in a social graph, you're running BFS or DFS in disguise.

typescript
// BFS for shortest-path in an unweighted dependency graph
function shortestPath(graph: Map<string, string[]>, start: string, end: string): string[] {
  const queue: string[][] = [[start]];
  const visited = new Set<string>([start]);

  while (queue.length > 0) {
    const path = queue.shift()!;
    const node = path.at(-1)!;

    if (node === end) return path;

    for (const neighbour of graph.get(node) ?? []) {
      if (!visited.has(neighbour)) {
        visited.add(neighbour);
        queue.push([...path, neighbour]);
      }
    }
  }
  return []; // no path
}

Dynamic Programming: Memoising Expensive Work

DP trains you to identify overlapping subproblems. In production this shows up everywhere: computing Fibonacci-style retry backoff, caching intermediate parsing results, or building a diff algorithm.

๐Ÿ’กThe two DP design steps translate directly to production memoisation: (1) define the subproblem clearly, (2) write the recurrence, then (3) replace recursion with a Map/cache. React's useMemo is literally step 3.
typescript
// Edit distance โ€” powers spell-checkers, git diff, fuzzy search
function editDistance(a: string, b: string): number {
  const dp: number[][] = Array.from({ length: a.length + 1 }, (_, i) =>
    Array.from({ length: b.length + 1 }, (_, j) => (i === 0 ? j : j === 0 ? i : 0))
  );

  for (let i = 1; i <= a.length; i++) {
    for (let j = 1; j <= b.length; j++) {
      dp[i][j] =
        a[i - 1] === b[j - 1]
          ? dp[i - 1][j - 1]
          : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
    }
  }
  return dp[a.length][b.length];
}

Binary Search Beyond Sorted Arrays

The key insight competitive programmers develop early: binary search works on any monotonic predicate, not just sorted arrays. "What's the minimum thread count that processes 10k jobs within 1 second?" โ€” binary search. "What's the smallest batch size that fits in memory?" โ€” binary search.

typescript
// Binary search on the answer โ€” find minimum workers to finish in time T
function minWorkers(jobs: number[], timeLimit: number): number {
  const canFinish = (workers: number): boolean => {
    // simulate round-robin assignment
    const workerTime = new Array(workers).fill(0);
    for (const job of jobs) {
      const minIdx = workerTime.indexOf(Math.min(...workerTime));
      workerTime[minIdx] += job;
    }
    return Math.max(...workerTime) <= timeLimit;
  };

  let lo = 1, hi = jobs.length;
  while (lo < hi) {
    const mid = (lo + hi) >> 1;
    canFinish(mid) ? (hi = mid) : (lo = mid + 1);
  }
  return lo;
}

Segment Trees: Range Query Patterns in Production

Competitive programmers learn segment trees for range minimum/sum queries. In production, the same pattern appears in time-series analytics, sliding-window aggregations, and interval scheduling. The mental model โ€” decompose a range into O(log n) precomputed segments โ€” is universally applicable.

The Meta-Skill: Reading the Problem Twice

Perhaps the most transferable skill is disciplined problem decomposition. Top competitive programmers always: (1) restate the problem in their own words, (2) enumerate constraints and edge cases before writing code, (3) identify the algorithmic category, then (4) code. Engineering teams that adopt this discipline ship significantly fewer regressions.

Written by

Md. Saniuzzaman Robin

Full-Stack Software Engineer

More Articles โ†’