回溯算法part02 算法

2024-01-08 00:32:38

回溯算法part02

今日内容:

● 216.组合总和III
● 17.电话号码的字母组合

1.LeetCode 216.组合总和III

https://leetcode.cn/problems/combination-sum-iii/

未剪枝版:

//未剪枝
class Solution {
    List<List<Integer>> result=new ArrayList<>();
    List<Integer> path=new ArrayList<>();
    public List<List<Integer>> combinationSum3(int k, int n) {
        //从集合中找出3个数,那就像上一道题那样,将值存进一维数组中(3个数),最后判断下是否和为n,如果是则加进二维集合
        backtracing(n,k,1,0);
        return result;
    }
    public void backtracing(int n,int k,int beginIndex,int addSum){
        int add=0;
        if(path.size()==k){
            if(addSum==n){
                result.add(new ArrayList<>(path));
                return;
            }
        }
        for(int i=beginIndex;i<=9;i++){
            addSum+=i;
            path.add(i);
            backtracing(n,k,i+1,addSum);
            addSum-=i;
            path.removeLast();
        }
    }
}

剪枝优化版:

//剪枝
//第一处要减的是因为要求是三个数和为n,那么只要遍历到节点后addSum已经大过n了,我们就就进行return 
//第二处剪枝的是本题要求的是三个数,那么当遍历到的位置后面元素个数加起来不能达到目标个数,我们就进行剪枝//也就是n-(k-path.size())+1//因为在for循环的递归传进去下一次要遍历的位置是i+1
class Solution {
    List<List<Integer>> result=new ArrayList<>();
    List<Integer> path=new ArrayList<>();
    public List<List<Integer>> combinationSum3(int k, int n) {
        //从集合中找出3个数,那就像上一道题那样,将值存进一维数组中(3个数),最后判断下是否和为n,如果是则加进二维集合
        backtracing(n,k,1,0);
        return result;
    }
    public void backtracing(int n,int k,int beginIndex,int addSum){
        if(addSum>n){
            return;
        }
        if(path.size()==k){
            if(addSum==n){
                result.add(new ArrayList<>(path));
                return;
            }
        }
        for(int i=beginIndex;i<=9-(k-path.size())+1;i++){
            addSum+=i;
            path.add(i);
            backtracing(n,k,i+1,addSum);
            addSum-=i;
            path.removeLast();
        }
    }
}

2.LeetCode17.电话号码的字母组合

https://leetcode.cn/problems/letter-combinations-of-a-phone-number/

class Solution {
    List<String> result=new ArrayList<>();
    //定义一个字符串存储每一次的
    StringBuilder letter=new StringBuilder();

    //保持数字和值(下标和值)
    //可以用字符串数组,也可以用哈希表
    String[] letterMap={
        "",
        "",
        "abc",
        "def",
        "ghi",
        "jkl",
        "mno",
        "pqrs",
        "tuv",
        "wxyz"
    };
    public List<String> letterCombinations(String digits) {
        if(digits.length()==0||digits==null){
            return result;
        }
        backtracing(digits,0);
        return result;
    }
    public void backtracing(String digits,int index){
        if(index==digits.length()){
            //加进结果中
            result.add(letter.toString());
            return;
        }
        //保存现在遍历到的数字(下标)
        int digit=digits.charAt(index)-'0';//因为digits[index]取出来的是字符,要转成数字
        //拿着现在的下标去保存letterMap的字母
        String wanletter=letterMap[digit];
        //遍历这个完整的字母(字符串)
        for(int i=0;i<wanletter.length();i++){
            //遍历第一层字符串,存进letter中
            letter.append(wanletter.charAt(i));
            backtracing(digits,index+1);
            letter.deleteCharAt(letter.length()-1);
        }
    }
}

文章来源:https://blog.csdn.net/Belle_Daisy/article/details/135445219
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。