Backtracking Algorithms for Combination Problems in LeetCode

Overview of Backtracking

Backtracking is a systematic way to explore all potential solutions by building combinations incrementally and backtracking when a path fails to meet constraints. It's particularly useful for problems like combinations, permutations, subsets, and other combinatorial searches.

Common problem types solved with backtracking include:

  • Combination problems: Selecting k elements from a set of n without considering order.
  • Sum-based combination problems: Finding combinations that sum up to a target.
  • Letter combination problems: Generating all possible letter combinations for a phone number input.

Combinations differ from permutations in that the order of elements does not matter in combinations.

LeetCode 77: Combinations

The task is to generate all possible combinations of k numbers chosen from 1 to n.

Approach:

  • Use a recursive backtracking function.
  • Maintain a temporary list to store the current combination.
  • When the combination reaches size k, add it to the result list.
  • Recursively choose the next number, ensuring no duplicates.

class Solution {
    public List<List<Integer>> combine(int n, int k) {
        List<List<Integer>> result = new ArrayList<>();
        List<Integer> current = new ArrayList<>();
        generate(result, current, n, k, 1);
        return result;
    }

    private void generate(List<List<Integer>> result, List<Integer> current, int n, int k, int start) {
        if (current.size() == k) {
            result.add(new ArrayList<>(current));
            return;
        }

        for (int i = start; i <= n; i++) {
            current.add(i);
            generate(result, current, n, k, i + 1);
            current.remove(current.size() - 1);
        }
    }
}

LeetCode 216: Combination Sum III

Find all unique combinations of k numbers that sum up to a target value n, using numbers from 1 to 9.

Approach:

  • Similar to the previous problem but with an additional sum constraint.
  • Track the remaining target sum during recursion.
  • Prune the search space when the sum exceeds the target or the combination size exceeds k.

class Solution216 {
    public List<List<Integer>> combinationSum3(int k, int target) {
        List<List<Integer>> result = new ArrayList<>();
        List<Integer> current = new ArrayList<>();
        generate(result, current, k, target, 1);
        return result;
    }

    private void generate(List<List<Integer>> result, List<Integer> current, int k, int remaining, int start) {
        if (current.size() == k && remaining == 0) {
            result.add(new ArrayList<>(current));
            return;
        }

        if (current.size() >= k || remaining < 0) {
            return;
        }

        for (int i = start; i <= 9; i++) {
            current.add(i);
            generate(result, current, k, remaining - i, i + 1);
            current.remove(current.size() - 1);
        }
    }
}

LeetCode 17: Letter Combinations of a Phone Number

Generate all possible letter combinations that a given phone number could represent, based on standard telephone keypad mappings.

Approach:

  • Create a mapping from digits to letters using a hash map.
  • Use backtracking to explore all combinations of letters.
  • Each recursive call processes the next digit and tries all its corresponding letters.

class Solution17 {
    private static final Map<Character, String> digitToLetters = new HashMap<>();

    static {
        digitToLetters.put('2', "abc");
        digitToLetters.put('3', "def");
        digitToLetters.put('4', "ghi");
        digitToLetters.put('5', "jkl");
        digitToLetters.put('6', "mno");
        digitToLetters.put('7', "pqrs");
        digitToLetters.put('8', "tuv");
        digitToLetters.put('9', "wxyz");
    }

    public List<String> letterCombinations(String digits) {
        List<String> result = new ArrayList<>();
        if (digits.isEmpty()) return result;

        backtrack(result, new StringBuilder(), digits, 0);
        return result;
    }

    private void backtrack(List<String> result, StringBuilder current, String digits, int position) {
        if (position == digits.length()) {
            result.add(current.toString());
            return;
        }

        char digit = digits.charAt(position);
        String letters = digitToLetters.get(digit);

        for (char letter : letters.toCharArray()) {
            current.append(letter);
            backtrack(result, current, digits, position + 1);
            current.deleteCharAt(current.length() - 1);
        }
    }
}

Tags: LeetCode backtracking Combinations Recursion java

Posted on Sat, 01 Aug 2026 17:00:22 +0000 by saras