方法:深度优先搜索DFS | 回溯
回溯算法框架:
res = []
def backtrack(路径,选择列表):
做剪枝
if 满足结束条件:
res.append(路径)
return
for 选择 in 选择列表:
做选择
backtrack(路径,选择列表)
撤销选择
解决一个回溯问题,实际上就是一个决策树的遍历过程:
1、路径:也就是已经做出的选择。
2、选择列表:也就是你当前可以做的选择。
3、结束条件:也就是到达决策树底层,无法再做选择的条件。
思路:
本题相比较模板,改动的地方就是backtrack()里的结束条件,在这里,只要调用backtrack()就满足条件
Python实现:
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
# 回溯
res = []
if not nums:
return res
def backtrack(start, path):
res.append(path[:])
for i in range(start, len(nums)):
path.append(nums[i])
backtrack(i + 1, path)
path.pop();
backtrack(0, [])
return res
C++实现:
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> subsets(vector<int>& nums) {
// 记录走过的路径
vector<int> track;
backtrack(nums, 0, track);
return res;
}
void backtrack(vector<int>& nums, int start, vector<int>& track) {
res.push_back(track);
for (int i = start; i < nums.size(); i++) {
// 做选择
track.push_back(nums[i]);
// 回溯
backtrack(nums, i + 1, track);
// 撤销选择
track.pop_back();
}
}
};
时间复杂度:O(n*2^n), 一共2^n个状态,每种状态需要O(n)的时间来构造子集
空间复杂度:O(n),临时数组t的空间代价是O(n),递归时栈空间的代价为O(n)