题目
Given a set of distinct integers, nums, return all possible subsets.
For example, If nums = [1,2,3], a solution is:
[ [], [1], [1,2], [1,2,3], [1,3], [2], [2,3], [3] ]要求: The solution set must not contain duplicate subsets.
可能要求:(Leetcode 没有要求但是面试可能)
Elements in a subset must be in non-descending order.
原题链接:
Leetcode
LintCode
思路
解题方向
可以把这题想像成一个tree, 不同的subset就是不同的tree node 然后从root 开始一个一个traverse.
这样很明显的我们就可以用搜索的方法来找到答案,这里我们采用深度优先搜索(DFS)的方式
subset不能降序问题
如果题目要求不能降序 (e.g. [1,2,3] 不能 [1,3,2]) 这样我们就要在 开始搜索之前先给 nums
排一下序
去重问题
一个可能遇见的问题就是采用了重复的 subset 的情况 在 graph 的搜索里一般我们会用一个单独的 array 来存访问过的 nodes
但是这个问题我们可以使用一个 startIndex
变量来记录当前traverse 到的数字,往下的搜索会从这个数字后开始。思路和 graph 也是相似的,相当于 startIndex 之前的 nodes/nums 都已经访问过了。
这样就不会出现,比如说,在 [2,3]
然后又往回加1变成 [2,3,1]
的情况了.
实现
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> result;
if (nums.size() == 0)
return result;
// first sort the nums
sort(nums.begin(), nums.end());
vector<int> subset;
dfsHelper(0, subset, nums, result);
return result;
}
void dfsHelper(int startIndex,
vector<int> & currSet,
vector<int> & nums,
vector<vector<int>> & result) {
// add current set to result
result.push_back(currSet);
// traverse all neighbor nodes
// use startIndex to avoid
// going back to previous nums
for (int i = startIndex; i < nums.size(); i++) {
// add something
currSet.push_back(nums[i]);
// recursive call
dfsHelper(i+1, currSet, nums, result);
// remove something
currSet.pop_back();
}
}
时间复杂度分析
总结
用 DFS 的时候可以参考模板,因为他们的步骤大概都是一样的
add current node
use a for loop to traverse all neighbor nodes
add this node to result
call recursive function on this node
remove this node
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。