首页 > Java > java教程 > LeetCode DayBackTracking 第 1 部分

LeetCode DayBackTracking 第 1 部分

WBOY
发布: 2024-07-16 17:45:48
原创
661 人浏览过

77. 组合

给定两个整数 n 和 k,返回从范围 [1, n] 中选择的 k 个数字的所有可能组合。

您可以按任意顺序返回答案。

示例1:

输入:n = 4,k = 2
输出:[[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
说明:共有 4 选 2 = 6 种组合。
请注意,组合是无序的,即 [1,2] 和 [2,1] 被认为是相同的组合。
示例2:

输入:n = 1,k = 1
输出:[[1]]
说明:共有 1 个选择 1 = 1 个总组合。

限制:

1 1

错误代码

    public List<List<Integer>> combine(int n, int k) {
        List<List<Integer>> list = new ArrayList<>();

        List<Integer> nums = new ArrayList<>();

        backTracking(list,1,1,n,k,nums);

        return list;
    }

    public void backTracking(List<List<Integer>> list, int base,int size,int n, int k,List<Integer> nums)
    {
        if(size>k){
            list.add(new ArrayList<>(nums));
            return;
        }

        for(int i=base; base<n; i++ ){
            nums.add(i);
            backTracking(list,i+1,size+1,n,k,nums);
            nums.remove(nums.size()-1);
        }
    }
登录后复制

但是会导致 LeetCode 出现 Memory Limit Exceeded 错误

这里有一些错误。

Image description

1,循环条件错误,应该使用i,但上面的代码使用base作为结束条件。
如图2所示,正确的阈值可以是n,并且如果i<n,则将错过当n是潜在组合的元素时的可能性。

精细代码

    public List<List<Integer>> combine(int n, int k) {
        List<List<Integer>> list = new ArrayList<>();

        List<Integer> nums = new ArrayList<>();

        backTracking(list,1,1,n,k,nums);

        return list;
    }

    public void backTracking(List<List<Integer>> list, int base,int size,int n, int k,List<Integer> nums)
    {
        if(size>k){
            list.add(new ArrayList<>(nums));
            return;
        }

        for(int i=base; i<=n; i++ ){
            nums.add(i);
            backTracking(list,i+1,size+1,n,k,nums);
            nums.remove(nums.size()-1);
        }
    }
登录后复制
    List<List<Integer>> list = new LinkedList<>();
    List<Integer> nums = new LinkedList<>();
    public List<List<Integer>> combine(int n, int k) {
        backTracking(1,n,k);
        return list;
    }

    public void backTracking(int base, int n, int k)
    {
        if(nums.size()==k){
            list.add(new ArrayList<>(nums));
            return;
        }

        for(int i=base; i<=n; i++ ){
            nums.add(i);
            backTracking(i+1,n,k);
            nums.removeLast();
        }
    }
登录后复制

Image description
这里有一些差异,我们可以直接依赖于全局路径列表的大小,但这里 nums 的大小是正确的答案!!!
之前的大小不是正确的答案,因为我们还没有将最后一个元素添加到路径列表中。

貌似采用全局变量会导致性能下降?

这是一种更通用的方法,但问题是我们只使用 = 1 的数字

    public List<List<Integer>> combinationSum3(int k, int n) {
        List<List<Integer>> list = new ArrayList<>();
        List<Integer> path = new LinkedList<>();
        backTracking(list, path, 1, k, n);
        return list;

    }

    public void backTracking(List<List<Integer>>list,  List<Integer> path, 
    int start, int k, int n){
        if(path.size() == k){
            int sum = path.stream().reduce(0,Integer::sum);
            if(sum == n){
                list.add(new ArrayList<>(path));
            }
        }
        for(int i=start ; i<=n; i++){
            int sum = path.stream().reduce(0,Integer::sum);
            if(sum>n){
                break;
            }
            path.add(i);
            backTracking(list,path,i+1, k,n );
            path.remove(path.size()-1);
        }
    }
登录后复制
    public List<List<Integer>> combinationSum3(int k, int n) {
        List<List<Integer>> list = new ArrayList<>();
        List<Integer> path = new LinkedList<>();
        backTracking(list, path, 1, k, n);
        return list;

    }

    public void backTracking(List<List<Integer>>list,  List<Integer> path, 
    int start, int k, int n){
        if(path.size() == k){
            int sum = path.stream().reduce(0,Integer::sum);
            if(sum == n){
                list.add(new ArrayList<>(path));
            }
        }
        for(int i=start ; i<=9; i++){
            int sum = path.stream().reduce(0,Integer::sum);
            if(sum>n){
                break;
            }
            path.add(i);
            backTracking(list,path,i+1, k,n );
            path.remove(path.size()-1);
        }
    }
登录后复制

sum 似乎使用了一些冗余计算

    public List<List<Integer>> combinationSum3(int k, int n) {
        List<List<Integer>> list = new ArrayList<>();
        List<Integer> path = new LinkedList<>();
        backTracking(list, path, 1, k, n, 0);
        return list;

    }

    public void backTracking(List<List<Integer>>list,  List<Integer> path, 
    int start, int k, int n, int sum){
        if(path.size() == k){
            if(sum == n){
                list.add(new ArrayList<>(path));
            }
        }
        for(int i=start ; i<=9; i++){
            sum += i;
            if(sum>n){
                break;
            }
            path.add(i);
            backTracking(list,path,i+1, k,n, sum);
            path.remove(path.size()-1);
            sum -= i;
        }
    }
登录后复制

17. 电话号码的字母组合

给定一个包含 2-9 数字的字符串,返回该数字可以代表的所有可能的字母组合。以任意顺序返回答案。

下面给出了数字到字母的映射(就像电话按钮一样)。请注意,1 不映射到任何字母。

Image description

示例1:

输入:数字=“23”
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例2:

输入:数字=“”
输出:[]
示例 3:

输入:数字=“2”
输出:["a","b","c"]

限制:

0 digits[i] 是 ['2', '9'] 范围内的数字。

    public List<String> letterCombinations(String digits) {
        List<String> list = new LinkedList<>();
        if(digits.length() == 0){
            return list;
        }
        String[] arr = {
            "",
            "",
            "abc",
            "def",
            "ghi",
            "jkl",
            "mno",
            "pqrs",
            "tuv",
            "wxyz"
        };
        backTracking(list, new StringBuilder(), 0, digits, arr);
        return list;

    }

    public void backTracking(List<String> list, StringBuilder s, int start, String digits, String[] arr){
        if(start == digits.length()){
            list.add(s.toString());
            return;
        }

        int num = digits.charAt(start)-'0';
        String button = arr[num];
        for(int i=0; i<button.length(); i++){
            s.append(button.charAt(i));
            backTracking(list, s, start+1, digits, arr);
            s.setLength(s.length()-1);
        }
    }
登录后复制

以上是LeetCode DayBackTracking 第 1 部分的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板