刷题日记05《回溯算法》

问题描述

力扣icon-default.png?t=N5K3https://leetcode.cn/problems/TVdhkn/

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

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

示例 1:

输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:

输入:nums = [0]
输出:[[],[0]]

提示:

  • 1 <= nums.length <= 10
  • -10 <= nums[i] <= 10
  • nums 中的所有元素 互不相同

解题思路

回溯问题的经典应用:求一个队列的子集合,要求子集合中不同顺序相同数字的集合也被认为是相同的集合。我们要面对的第一个问题是:如何保证我们最终的求解问题中不包含重复的集合呢?我使用的方法是:使用队列中数字的相对位置,即不改变队列中的相对位置,跳跃性的选择当前位置是否加入目标队列,接下来我们讲解整体思路:设置下标,从第一个数字开始,每一个数字都有加入和不加入目标队列两种选择,当下标指向最后一个元素后方时,将当前数据集加入结果队列即可(这样也保证了数字间的相对位置:只能从前往后进行选择)

实例代码

class Solution {
    private LinkedList<List<Integer>>res=new LinkedList<>();
    private LinkedList<Integer>data=new LinkedList<>();
    public List<List<Integer>> subsets(int[] nums) {
        reverse(nums,0);
        return res;
    }
    public void reverse(int[]nums,int index){
        //递归出口
        if(index==nums.length){
            res.add(new ArrayList(data));
            return ;
        }
        //先递归没有下标的
        reverse(nums,index+1);
        data.addLast(nums[index]);
        reverse(nums,index+1);
        //回溯
        data.removeLast();

    }
}

时间复杂度O(N*2^N)  空间复杂度:O(N)

问题描述

给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。

示例 1:

输入: n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]
示例 2:

输入: n = 1, k = 1
输出: [[1]]

 

提示:

1 <= n <= 20
1 <= k <= n

解题思路

与上题思路完全一致,但是需要在最后的终止条件时判断是否满足了当前个数,如果满足则加入目标队列,不满足则无需加入

实例代码

class Solution {
    private List<List<Integer>>res=new LinkedList<>();
    private LinkedList<Integer>data=new LinkedList<>();
    public List<List<Integer>> combine(int n, int k) {
        //创建数组
        int[]arr=new int[n];
        for(int i=1;i<=n;++i){
            arr[i-1]=i;
        }
        //调用函数
        reverse(0,arr,k);
        return res;
    }
    public void reverse(int index,int[]arr,int k){
        //递归出口
        if(index==arr.length){
            if(data.size()==k){
                res.add(new LinkedList(data));
            }
            return;
        }
        //进行递归
        reverse(index+1,arr,k);
        data.addLast(arr[index]);
        reverse(index+1,arr,k);
        //回溯
        data.removeLast();
    }

}

猜你喜欢

转载自blog.csdn.net/m0_65431718/article/details/131534094