day26

1、leetcode39 组合总和

class Solution {
    List<Integer> path = new LinkedList<Integer>();
    List<List<Integer>> res = new ArrayList<>();
    int sum;

    public void backTracking(int[] candidates, int target, int startIndex) {
        if(sum == target){
            res.add(new ArrayList<>(path));
            return;
        }
		
        // 如果 sum + candidates[i] > target 就终止遍历
        for(int i=startIndex; i<candidates.length && sum + candidates[i] <= target; i++){
            sum += candidates[i];
            path.add(candidates[i]);
            backTracking(candidates, target, i);
            sum -= candidates[i];
            path.remove(path.size()-1);
        }
    }

    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        Arrays.sort(candidates);// 需要先排序【通过先排序进行剪枝优化】
        backTracking(candidates, target, 0);
        return res;
    }
}

2、leetcode40 组合总和Ⅱ

class Solution {
    List<Integer> path = new LinkedList<Integer>();
    List<List<Integer>> res = new ArrayList<>();
    int sum;

    public void backTracking(int[] candidates, int target, int startIndex) {
        if(sum == target){
            res.add(new ArrayList<>(path));
            return;
        }

        for(int i=startIndex; i<candidates.length && sum+candidates[i]<=target; i++){
            // 要对同一树层使用过的元素进行跳过
            if(i>startIndex  && candidates[i]==candidates[i-1]){
                continue;
            }
            sum += candidates[i];
            path.add(candidates[i]);
            backTracking(candidates, target, i+1);// 和39.组合总和的区别1,这里是i+1,每个数字在每个组合中只能使用一次
            sum -= candidates[i];
            path.remove(path.size()-1);
        }
    }

    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        Arrays.sort(candidates);// 首先把给candidates排序,让其相同的元素都挨在一起。
        backTracking(candidates, target, 0);
        return res;
    }
}

3、leetcode131 分割回文串

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

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

    public void backTracking(String s, int startIndex) {
        // 如果起始位置已经大于s的大小,说明已经找到了一组分割方案
        if(startIndex>=s.length()){
            res.add(new ArrayList<>(path));
            return;
        }

        for(int i=startIndex; i<s.length(); i++){
            if(isPalindrome(s,startIndex,i)){ // 是回文子串
                // 获取[startIndex,i]在s中的子串
                String str = s.substring(startIndex, i+1);
                path.add(str);
            }else {// 不是回文,跳过
                continue;
            }
            backTracking(s,i+1);// 寻找i+1为起始位置的子串
            path.remove(path.size()-1);// 回溯

        }
    }

    public List<List<String>> partition(String s) {
        backTracking(s, 0);
        return res;
    }
}
posted @ 2023-02-13 23:57  黄三七  阅读(19)  评论(0)    收藏  举报