day23 回溯算法-sum1+sum2+PalindromePartitioning

### 7.5 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.
https://programmercarl.com/0039.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8C.html 

```java
public class combinationSum39 {  
    List<List<Integer>> result = new LinkedList<>();  
    LinkedList<Integer> path = new LinkedList<>();  
    public List<List<Integer>> combinationSum(int[] candidates, int target) {  
        Arrays.sort(candidates);  
        backtracking(candidates,target,0,0);  
        return result;  
    }  
    private void backtracking(int[] candidates, int target, int sum,int startIndex){  
//        if(sum > target){  
//            return;  
//        }  
        if(sum == target){  
            result.add(new ArrayList<>(path));  
            return;  
        }  
        for (int i = startIndex; i < candidates.length; i++) {  
            //将上面的if(sum > target) return;替换为这句以后,代码效率大大提高了。  
            if(sum + candidates[i] > target) break;  
            path.add(candidates[i]);  
            sum += candidates[i];  
            //这里允许元素重复,所以无需i++  
            backtracking(candidates,target,sum,i);  
            sum -= candidates[i];  
            path.removeLast();  
        }  
  
    }  
}  
class combinationSum39Test {  
    public static void main(String[] args) {  
        int[] candidates = {2,3,5};  
        combinationSum39 example = new combinationSum39();  
        List<List<Integer>> result = example.combinationSum(candidates,8);  
        for(List<Integer> levels :result){  
            System.out.print("[");  
            for(int nums : levels){  
                System.out.print(nums+" ");  
            }  
            System.out.println("]");  
        }  
    }  
}
```

### 7.6 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.
https://programmercarl.com/0040.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8CII.html   
去重:数层去重/树枝去重。
本题重点在于数层去重。通过长度和candidates一致的used数组实现,用过的数组标为1,没用过的元素位置是0。
`candidates[i-1] == candidates[i] && used[i-1] == 0意味着前一位重复元素之前没有在同一层遍历上使用过,这种情况需要做去重。直接continue,不处理后面的数据即可。
![[sumCombination40.png]]
```java
public class sumCombination40 {  
    List<List<Integer>> result = new LinkedList<>();  
    LinkedList<Integer> path = new LinkedList<>();  
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {  
        int[] used = new int[candidates.length];  
        Arrays.sort(candidates);  
        backtracking(candidates,target,0,0,used);  
        return result;  
    }  
    private void backtracking(int[] candidates, int target, int sum, int startIndex, int[] used){  
        if(sum == target){  
            result.add(new ArrayList<>(path));  
            return;  
        }  
        for (int i = startIndex; i < candidates.length; i++) {  
            if(sum + candidates[i] > target) break;  
            if(i > 0 && candidates[i] == candidates[i-1] && used[i-1] == 0) continue;  
            path.add(candidates[i]);  
            sum += candidates[i];  
            used[i] = 1;  
            backtracking(candidates,target,sum,i+1,used);  
            path.removeLast();  
            sum -= candidates[i];  
            used[i] = 0;  
        }  
    }  
}  
class sumCombination40Test {  
    public static void main(String[] args) {  
        int[] candidates = {10,1,2,7,6,1,5};  
        sumCombination40 example = new sumCombination40();  
        List<List<Integer>> result = example.combinationSum2(candidates,8);  
        for(List<Integer> levels :result){  
            System.out.print("[");  
            for(int nums : levels){  
                System.out.print(nums+" ");  
            }  
            System.out.println("]");  
        }    
    }  
}
```

### 7.7 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.
A palindrome is a string that reads the same forward and backward.
https://programmercarl.com/0131.%E5%88%86%E5%89%B2%E5%9B%9E%E6%96%87%E4%B8%B2.html  
不会的地方:
1.切割多个不懂长度的字符串
`[startIndex,i]:子串范围
```java
public class palindromePartition {  
    List<List<String>> result = new LinkedList<>();  
    LinkedList<String> path = new LinkedList<>();  
    public List<List<String>> partition(String s) {  
        backtracking(s,0);  
        return result;  
    }  
    private void backtracking(String s, int startIndex){  
        //System.out.println("Entering partitioning with startIndex = " + startIndex + " path = " + path);  
        if(startIndex == s.length()){  
            result.add(new ArrayList<>(path));  
            return;  
        }  
        for (int i = startIndex; i < s.length(); i++) {  
            if(isPalindrome(s,startIndex,i)){  
                path.add(s.substring(startIndex,i+1));  
            }else{  
                continue;  
            }  
            backtracking(s,i+1);  
            //System.out.println("In the for cycle with i = " + i + " path.last = " + path.getLast() + " startIndex= " + startIndex);  
            path.removeLast();  
        }  
        //System.out.println("End partitioning with startIndex = " + startIndex + " path = " + path);  
    }  
    private boolean isPalindrome(String s, int start, int end){  
        while(end > start){  
            if(s.charAt(end) != s.charAt(start)) return false;  
            end--;  
            start++;  
        }  
        return true;  
    }  
}  
class palindromePartitionTest {  
    public static void main(String[] args) {  
        palindromePartition example = new palindromePartition();  
        List<List<String>> result = example.partition("aab");  
        for(List<String> levels :result){  
            System.out.print("[");  
            for(String s : levels){  
                System.out.print(s+" ");  
            }  
            System.out.println("]");  
        }  
  
    }  
}
```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值