Algorithm Solving Techniques

When faced with algorithmic problems, choosing the right strategy is as important as implementing the solution. Here are four fundamental techniques that serve as the foundation for most algorithmic solutions.

1. Brute Force

This technique explores all possible options to find a solution. While simple to implement, it's often inefficient.

Example: Find a pair with a given sum

function hasPairWithSum(arr, sum) {
  for (let i = 0; i < arr.length; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[i] + arr[j] === sum) return true;
    }
  }
  return false;
}

2. Greedy Algorithms

Greedy methods build a solution step by step, always choosing the local optimum. This works for problems where local choices lead to a global solution.

Example: Coin Change (Greedy)

Choose the largest coin possible at each step. This works for standard denominations but may fail in arbitrary systems.

3. Divide and Conquer

This technique splits the problem into smaller subproblems, solves them recursively, and combines the results.

Example: Merge Sort

function mergeSort(arr) {
  if (arr.length <= 1) return arr;
  const mid = Math.floor(arr.length / 2);
  const left = mergeSort(arr.slice(0, mid));
  const right = mergeSort(arr.slice(mid));
  return merge(left, right);
}

4. Dynamic Programming (DP)

DP solves problems by breaking them into overlapping subproblems and storing the results of subproblems to avoid redundant work.

Example: Fibonacci with Memoization

function fib(n, memo = {}) {
  if (n <= 1) return n;
  if (memo[n]) return memo[n];
  memo[n] = fib(n - 1, memo) + fib(n - 2, memo);
  return memo[n];
}

Final Thoughts

Understanding these core techniques is essential for improving your problem-solving skills. Over time, you'll learn to recognize which strategy applies best to different problem types — and how to combine them for more complex scenarios.