SubSet 这题有4种解法,其中DFS两种,BFS一种,位运算一种。
解法1:
DFS 通用回溯解法。
注意:
1) 是每次进入helper()的sol都是一个解,所以不用等到index=nums.size()再存到results里面。
2) vector < vector < int> > results;
results的值会是[]。如果想让它变成[[]],要用results.push_back(vector());
class Solution {
public:
/**
* @param nums: A set of numbers
* @return: A list of lists
*/
vector<vector<int>> subsets(vector<int> &nums) {
vector<vector<int> > results;
vector<int> sol;
if (nums.empty()) {
results.push_back(vector<int>());
return results;
}
sort(nums.begin(), nums.end());
helper(nums, 0, sol, results);
return results;
}
void helper(vector<int> &nums, int index, vector<int>&sol, vector<vector<int>> &results) {
results.push_back(sol);
for (int i=index; i<nums.size(); ++i) {
sol.push_back(nums[i]);
helper(nums, i+1, sol, results);
sol.pop_back();
}
}
};
解法4:位运算
vector<vector<int>> subsets(vector<int> &nums) {
vector<vector<int> > solution;
vector<int> singleSol;
int numSize=nums.size();
int totalNum=pow(2,numSize)-1;
solution.push_back(singleSol);
for (int i=1; i<=totalNum; ++i) {
singleSol.clear();
for(int j=0; j<numSize; ++j) {
int bitNum = (i>>j)&0x1;
if (bitNum==1) {
singleSol.push_back(nums[j]);
}
sort(singleSol.begin(), singleSol.end());
}
solution.push_back(singleSol);
}
return solution;
}
效率可能还要改进一下。
另外2种下次写。
另外分析一下算法复杂度。关于DFS的时间复杂度是O(答案个数×构造每个答案时间)。所以以上DFS的时间复杂度都是O(n*2^n)。
SubSet II 和SubSet类似,但是要注意去重。
以通用回溯解法为例:
vector<vector<int>> subsetsWithDup(vector<int> &nums) {
vector<vector<int>> results;
vector<int> sol;
if (nums.empty()) {
results.push_back(vector<int>());
return results;
}
sort(nums.begin(), nums.end());
helper(nums, 0, sol, results);
return results;
}
void helper(vector<int>&nums, int index, vector<int>&sol, vector<vector<int>>&results) {
results.push_back(sol);
for (int i=index; i<nums.size(); ++i) {
if ((i!=index) && (nums[i-1]==nums[i])) //去重
continue;
sol.push_back(nums[i]);
helper(nums, i+1, sol, results);
sol.pop_back();
}
}
为啥这个可以去重呢? 以[1,2,2]为例,
if ((i!=index) && (nums[i-1]==nums[i])) //去重
continue;
参考上面的代码,
第2行,取到[2]之后,就不会取第2个2了。
第3行,取到[1,2]之后,不会再取下一个[1,2]。同时它继续调用helper(,index+1,) 这里index+1=2,所以进helper()之后,index=2, i=2==index(第一次),所以第4行还是会有[1,2,2]。
同样,回溯到[2]之后会继续调用helper(,index+1,)。这里index+1=2。所以第3行还是会有[2,2],因为i==index。