回溯

作者: 你大爷终归是你大爷 | 来源:发表于2022-06-05 11:47 被阅读0次

    回朔算法是使用递归的方式,遍历所有的状态,一般借助数组等结构进行“剪枝”,较少遍历的次数。

    解决的是 子集、组合、排列 问题。注意边界条件。
    子集和排列和顺序无关,要借助位置信息防止重复;
    排列和位置无关,只需判断辅助数据结构(path)中是否包含当前元素

    下文介绍这几种的标准代码。

    1、子集

    力扣78题:给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

    class Solution {
    
        List<List<Integer>> res = new ArrayList();
        List<Integer> path = new ArrayList();
    
        public List<List<Integer>> subsets(int[] nums) {
            dfs(nums, 0);
            return res;
        }
    
        // 注意index的用法
        public void dfs(int[] nums, int index) {
            res.add(new ArrayList(path));
            for(int i=index;i<nums.length;i++) {
                path.add(nums[i]);
                dfs(nums, i+1);
                path.remove(path.size()-1);
            }
        }
    }
    

    2、组合

    组合是在子集的基础上进行剪枝,过程中不匹配直接返回,不在继续递归。
    力扣77:给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。

    class Solution {
    
        List<List<Integer>> res = new ArrayList();
        List<Integer> path = new ArrayList();
    
        public List<List<Integer>> combine(int n, int k) {
            dfs(n, k, 1);
            return res;
        }
    
        public void dfs(int n, int k, int index) {
            // 剪枝:组合是特定的子集,保留符合的
            if(k == path.size()) {
                res.add(new ArrayList(path));
                return ;
            }
            for(int i=index;i<=n;i++) {
                path.add(i);
                dfs(n, k, i+1);
                path.remove(path.size()-1);
            }
        }
    }
    

    3、排列

    力扣46题: 全排列 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

    class Solution {
    
        List<List<Integer>> res = new ArrayList();
        List<Integer> path = new ArrayList();
    
        public List<List<Integer>> permute(int[] nums) {
            dfs(nums);
            return res;
        }
    
        public void dfs(int[] nums) {
            if(path.size() == nums.length) {
                res.add(new ArrayList(path));
                return;
            }
            for(int i=0;i<nums.length;i++) {
                if(path.contains(nums[i])) {
                    continue;
                }
                path.add(nums[i]);
                dfs(nums);
                path.remove(path.size()-1);
            }
    
        }
    }
    

    相关文章

      网友评论

          本文标题:回溯

          本文链接:https://www.haomeiwen.com/subject/xvqzprtx.html