力扣热题100 - 回溯:子集

题目描述:

题号:78

图片

解题思路:

思路一:回溯

回溯是什么?

回溯算法(Backtracking Algorithm)是一种通过尝试不同的选择并逐步构建解决方案,以解决问题的方法。如果在某个步骤发现当前选择无法构成有效的解决方案,则算法会“回溯”到上一步,尝试其他选择。这种方法通常用于解决那些可以分解为多个子问题,并且需要找到所有或某些满足特定条件的解的问题。

回溯算法通常涉及以下步骤:

  1. 选择:在当前状态下选择一个选项进行尝试。

  2. 约束检查:检查当前选择是否满足问题的约束条件。

  3. 进一步探索:如果当前选择满足条件,则继续在下一个状态进行选择,即递归地调用自身。

  4. 撤销选择:如果当前选择无法构成有效解或所有可能的选择都已尝试,则撤销该选择,回溯到上一步,尝试其他选项。

  5. 结束条件:当找到一个完整且有效的解决方案,或确定没有更多可能的方案时,结束算法。

本题关键点:逐个递归,将每个元素都包含一遍。不能重复,一次每次都输入  i + 1 作为下一次递归的起点

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

空间复杂度:O(N) 

C++


// C++
class Solution {
    vector<int> temp;
    vector<vector<int>> answer;
    void backTrace(vector<int>& nums, int index) {
        answer.push_back(temp);

        for(int i = index; i < nums.size(); i++) {
            temp.push_back(nums[i]);
            backTrace(nums, i + 1);
            temp.pop_back();
        }
    }
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        if(nums.size() == 0) {
            return {};
        }

        backTrace(nums, 0);
        return answer;
    }
};

go


// go
func subsets(nums []int) [][]int {
    if len(nums) == 0 {
        return nil
    }
    temp := []int{}
    answer := [][]int{}
    var backTrace func(int)
    backTrace = func(index int) {
        answer = append(answer, slices.Clone(temp))

        for i := index; i < len(nums); i++ {
            temp = append(temp, nums[i])
            backTrace(i + 1)
            temp = temp[:len(temp) - 1]
        }
    }

    backTrace(0)
    return answer
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值