DEV Community

Dev Cookies
Dev Cookies

Posted on

Blog 9: Optimization with Pruning in Backtracking ✂️

Backtracking by itself explores the entire solution space, which can be exponential. But in many problems, we don’t need to explore every path.
That’s where pruning comes in — cutting off branches of the decision tree that can’t possibly lead to an optimal (or valid) solution.

This idea is also known as Branch & Bound in optimization problems.


🔹 Why Pruning Matters?

  • Without pruning → exponential time.
  • With pruning → we can reduce the search space drastically.
  • Pruning avoids wasted exploration of invalid or suboptimal branches.

🔹 Types of Pruning

  1. Constraint-based pruning – Stop exploring if current state is invalid.
  2. Bound-based pruning – Stop exploring if best possible result from this branch is worse than the current best.
  3. Early stopping – Return as soon as a solution is found (for decision problems like “does a path exist?”).

🔹 Problem 1: Knapsack (Branch & Bound)

Maximize profit by selecting items with weight constraints.

At each step:

  • Include or exclude an item.
  • Bound check: If total weight > capacity, prune branch.

Java Code

public class Knapsack { private static int maxProfit = 0; public static int knapSack(int[] weights, int[] values, int capacity) { backtrack(0, 0, 0, weights, values, capacity); return maxProfit; } private static void backtrack(int index, int currWeight, int currValue, int[] weights, int[] values, int capacity) { if (currWeight > capacity) return; // prune maxProfit = Math.max(maxProfit, currValue); if (index == weights.length) return; // include item backtrack(index + 1, currWeight + weights[index], currValue + values[index], weights, values, capacity); // exclude item backtrack(index + 1, currWeight, currValue, weights, values, capacity); } public static void main(String[] args) { int[] weights = {2, 3, 4}; int[] values = {4, 5, 6}; System.out.println(knapSack(weights, values, 5)); // Output: 9 } } 
Enter fullscreen mode Exit fullscreen mode

🔹 Problem 2: Word Search (LeetCode 79) with Early Pruning

Find if a word exists in a board by moving up/down/left/right.

Pruning: stop as soon as the character doesn’t match.

public class WordSearch { public boolean exist(char[][] board, String word) { for (int i = 0; i < board.length; i++) { for (int j = 0; j < board[0].length; j++) { if (dfs(board, word, i, j, 0)) return true; } } return false; } private boolean dfs(char[][] board, String word, int i, int j, int idx) { if (idx == word.length()) return true; if (i < 0 || j < 0 || i >= board.length || j >= board[0].length) return false; if (board[i][j] != word.charAt(idx)) return false; // prune mismatch char temp = board[i][j]; board[i][j] = '#'; // mark visited boolean found = dfs(board, word, i + 1, j, idx + 1) || dfs(board, word, i - 1, j, idx + 1) || dfs(board, word, i, j + 1, idx + 1) || dfs(board, word, i, j - 1, idx + 1); board[i][j] = temp; // unmark return found; } } 
Enter fullscreen mode Exit fullscreen mode

🔹 Problem 3: N-Queens with Pruning

In Blog 5 we solved N-Queens with full backtracking. But with pruning:

  • Stop if placing a queen is invalid (row/col/diagonal conflict).
  • Maintain cols, diag1, diag2 sets instead of checking every row each time.

This improves from O(N! full search) to much faster.


🔹 Problem 4: Sudoku Solver

Pruning is critical:

  • Stop exploring invalid placements early.
  • Use constraint propagation (pre-check row, col, subgrid).

🔹 More Problems Where Pruning Helps

  • Max Score Path in Grid – prune paths with score < current best.
  • Traveling Salesman (TSP) – bound on partial cost.
  • Partition Problems (Equal Subset, Palindrome Partitioning).
  • Graph Coloring – stop when adjacent nodes conflict.

🔹 Key Takeaways

✅ Always think: Can I detect invalidity early?
✅ Track best-so-far → prune worse candidates.
✅ Constraint pruning + bound pruning = exponential → polynomial improvements in practice.


Top comments (0)