第七章 回溯算法part03

71 阅读1分钟

39. Combination Sum

Given an array of distinct integers candidates and a target integer target, return a list of all unique combinations of candidates where the chosen numbers sum to target .  You may return the combinations in any order.

The same number may be chosen from candidates an unlimited number of times. Two combinations are unique if the frequency of at least one of the chosen numbers is different.

The test cases are generated such that the number of unique combinations that sum up to target is less than 150 combinations for the given input.

题目解析:

  • 使用回溯
  • 同一元素可以使用多次,所以为了避免重复需要先进行排序,而且下一次还是从同一位置i开始,而不是i+1

代码:

class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        Arrays.sort(candidates);
        List<List<Integer>> result = new ArrayList<>();
        backtracking(candidates, target, 0, new ArrayList<>(), result);
        return result;
    }

    public void backtracking(int[] candidates, int target, int start, List<Integer> comb, List<List<Integer>> result) {
        if (target <= 0) {
            if (target == 0) {
                result.add(new ArrayList<>(comb));
            }
            return;
        }
        for (int i = start; i < candidates.length; i++) {
            target -= candidates[i];
            comb.add(candidates[i]);
            backtracking(candidates, target, i, comb, result);
            target += candidates[i];
            comb.remove(comb.size() - 1);
        }
    }
}

40. Combination Sum II

Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sum to target.

Each number in candidates may only be used once in the combination.

Note: The solution set must not contain duplicate combinations.

题目解析:

  • 因为candidates中可能存在重复的元素,为了保证结果中不存在重复的元素,需要:
    • 先排序
    • 在同一个combination中可以存在多个相同的元素(如果candidates中有多个该元素),但是在不同的combination中只能只用一次,所以:if (i > startIndex && candidates[i] == candidates[i-1]) continue;

代码:

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<Integer> path = new ArrayList<>();
        Arrays.sort(candidates);
        backtracking(candidates, target, 0, path);
        return result;
    }

    public void backtracking(int[] candidates, int target, int startIndex, List<Integer> path) {
        if (target <= 0) {
            if (target == 0) {
                result.add(new ArrayList<>(path));
            }
            return;
        }
        for (int i = startIndex; i < candidates.length; i++) {
            if (i > startIndex && candidates[i] == candidates[i-1]) continue;
            path.add(candidates[i]);
            backtracking(candidates, target - candidates[i], i + 1, path);
            path.remove(path.size() - 1);
            
        }
    }
}

131. Palindrome Partitioning

Given a string s, partition s such that every substring of the partition is a palindrome. Return all possible palindrome partitioning of s.

题目解析:

  • 回溯,需要判断当前字符串是否为回文串

代码:

class Solution {
    public List<List<String>> partition(String s) {
        List<List<String>> result = new ArrayList<>();
        backtracking(s, 0, new ArrayList<>(), result);
        return result;
    }

    public void backtracking(String s, int start, List<String> comb, List<List<String>> result) {
        if (start >= s.length()) {
            result.add(new ArrayList<>(comb));
            return;
        }
        for (int i = start; i < s.length(); i++) {
            if (isPalindrome(s, start, i)) {
                comb.add(s.substring(start, i+1));
                backtracking(s, i + 1, comb, result);
                comb.remove(comb.size() - 1);
            }
        }
    }

    public boolean isPalindrome(String s, int start, int end) {
        while (start < end) {
            if (s.charAt(start) != s.charAt(end)) {
                return false;
            }
            start++;
            end--;
        }
        return true;
    }
}

总结

1。组合问题需要考虑去重