代码随想录训练营二刷第二十七天 | 39. 组合总和 40.组合总和II 131.分割回文串

代码随想录训练营二刷第二十七天 | 39. 组合总和 40.组合总和II 131.分割回文串

一、39. 组合总和

题目链接:https://leetcode.cn/problems/combination-sum/
思路:可重复取数,不用从下一位开始。早停需要先排序,以免大的数在前面小的数在后面漏了情况。

class Solution {
    List<List<Integer>> arrayLists = new ArrayList<>();
    List<Integer> list = new ArrayList<>();
    int sum = 0;
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        Arrays.sort(candidates);
        backTracking(candidates, target, 0);
        return arrayLists;
    }
    void backTracking(int[] candidates, int target, int index) {
        if (sum == target) {
            arrayLists.add(new ArrayList<>(list));
            return;
        }
        for (int i = index; i < candidates.length; i++) {
            if (sum + candidates[i] > target) break;
            sum += candidates[i];
            list.add(candidates[i]);
            backTracking(candidates, target, i);
            list.remove(list.size()-1);
            sum -= candidates[i];
        }
    }
}

二、40.组合总和II

题目链接:https://leetcode.cn/problems/combination-sum-ii/
思路:数组内有重复数字,但要求结果集不能重复且数组内数组不可以重复取,即和为4可以有1,1,2,但是不能还有1,2,1.从根节点到叶节点一路向下递归,无需去重,但是树层需要去重,相同的一个数在树层的左边选择了,那么该数后面的数也会选,当前节点也会选就会重复,所以要去重。

class Solution {
    List<List<Integer>> arrayLists = new ArrayList<>();
    List<Integer> list = new ArrayList<>();
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        Arrays.sort(candidates);
        boolean[] used = new boolean[candidates.length];
        backTracking(candidates, target, 0, 0, used);
        return arrayLists;
    }

    void backTracking(int[] candidates, int target, int index, int sum, boolean[] used) {
        if (sum == target) {
            arrayLists.add(new ArrayList(list));
            return;
        }
        for (int i = index; i < candidates.length && sum + candidates[i] <= target; i++) {
            if (i > 0 && candidates[i] == candidates[i-1] && used[i-1] == false) {
                continue;
            }
            list.add(candidates[i]);
            sum += candidates[i];
            used[i] = true;
            backTracking(candidates, target, i + 1, sum, used);
            used[i] = false;
            sum -= candidates[i];
            list.remove(list.size()-1);
        }
    }
}

三、131.分割回文串

题目链接:https://leetcode.cn/problems/palindrome-partitioning/
思路:字符串切割完毕即为终止叶节点,判断是否是是回文使用双指针

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

    void backTracking(String s, int index) {
        if (index >= s.length()) {
            arrayLists.add(new ArrayList<>(list));
        }
        for (int i = index; i < s.length(); i++) {
            if (!isHui(s, index, i)) continue;
            list.add(s.substring(index, i+1));
            backTracking(s, i + 1);
            list.remove(list.size() - 1);
        }
    }
    boolean isHui(String s, int left, int right) {
        if (left == right) return true;
        while (left < right) {
            if (s.charAt(left) != s.charAt(right)) return false;
            left++;
            right--;
        }
        return true;
    }
}

你可能感兴趣的:(力扣算法题,算法,数据结构)