算法训练营第二十七天|39. 组合总和、40.组合总和II、131.分割回文串

73 阅读1分钟

39. 组合总和

class Solution {
    LinkedList<Integer> path = new LinkedList<>();
    List<List<Integer>> res = new LinkedList<>();
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        backtrack(candidates, target, 0);
        return res;
    }
    private void backtrack(int[] candidates, int target, int stIdx){
        if(target < 0)return;

        if(target == 0){
            res.add(new LinkedList<>(path));
            return;
        }

        for(int i = stIdx; i < candidates.length; i++){
            path.add(candidates[i]);
            backtrack(candidates, target - candidates[i], i); // 控制回溯的startIndex不变,意为可以重复选取
            path.removeLast();
        }
    }
}

40. 组合总和 II

class Solution {
    LinkedList<Integer> path = new LinkedList<>();
    List<List<Integer>> res = new LinkedList<>();
    int trackSum = 0;
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        if(candidates.length == 0)return res;
        Arrays.sort(candidates);
        backtrack(candidates, 0, target);
        return res;
    }
    private void backtrack(int[] candidates, int start, int target){
        if(trackSum > target)return;
        if(trackSum == target)res.add(new LinkedList<>(path));

        for(int i = start; i < candidates.length; i++){
            // 剪枝
            if(i > start && candidates[i] == candidates[i - 1]){
                continue;
            }

            path.add(candidates[i]);
            trackSum += candidates[i];
            backtrack(candidates, i + 1, target);
            path.removeLast();
            trackSum -= candidates[i];
        }
    }
}

131. 分割回文串

class Solution {
    LinkedList<String> path = new LinkedList<>();
    List<List<String>> res = new LinkedList<>();

    public List<List<String>> partition(String s) {
        backtrack(s, 0);
        return res;
    }
    private void backtrack(String s, int start){
        if(start == s.length()){
            // 走到叶子节点
            // 即整个s被成功分割为若干回文子串,记下答案
            res.add(new LinkedList<String>(path));
        }

        for(int i = start; i < s.length(); i++){
            if(!isPalindrome(s, start, i)){
                // s[start .. i]不是回文串,不能分割
                continue;
            }
            // s[start .. i]是回文串的情况
            path.addLast(s.substring(start, i + 1));
            backtrack(s, i + 1);
            path.removeLast();
        }
    }

    // 双指针判断s[low .. high] 是否是一个回文串
    private boolean isPalindrome(String s, int low, int high){
        while(low < high){
            if(s.charAt(low) != s.charAt(high)){
                return false;
            }
            low++;
            high--;
        }
        return true;
    }
}