您的位置:首页 > 其它

leetcode-78-subsets

2017-01-04 21:44 357 查看

问题

题目:[leetcode-78]

思路

枚举所有子集,dfs即可。剪枝即之前元素出现过不行。

代码

class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
std::vector< std::vector<int> > ret;
std::vector<int> tmp;
ret.push_back(tmp);

std::map< int, bool > mapper;
dfs( 0, nums, mapper, tmp, ret );

return ret;
}
private:
void dfs( int depth, const std::vector<int>& nums, std::map<int, bool>& visit,
std::vector<int>& tmp, std::vector< std::vector<int> >& ret){

if( depth == nums.size() ) return;
else{
int sz = nums.size();
for( int i = 0; i < sz; ++i )
{
// 不同试探状态之间彼此不能影响
std::map<int, bool> __visit = visit;
std::vector<int> __tmp = tmp;

// 试探成功
if( !__visit[nums[i]] )
{
__visit[nums[i]] = true;
__tmp.push_back( nums[i] );
ret.push_back( __tmp );

dfs( depth + 1, nums, __visit, __tmp, ret );
}
}
}

}
};


上面的代码过不了,因为题目要求全部是增量子集。上面的序列会产生全部的子集

[[],[1],[1,2],[1,2,3],[1,3],[1,3,2],[2],[2,1],[2,1,3],[2,3],[2,3,1],[3],[3,1],[3,1,2],[3,2],[3,2,1]]

对于增量,需要做两处剪枝,每次试探从当前层次开始。但是,这并不能解决所有问题,应有有可能,第一层就试探非常大的元素。所以,还需要判断当前元素是否比之前元素大,只有大才可以。其实,这个剪枝就够了。但是,前面的剪枝毕竟可以减少搜索空间。

代码1

class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
std::vector< std::vector<int> > ret;
std::vector<int> tmp;
ret.push_back(tmp);

std::sort(nums.begin(), nums.end());
std::map< int, bool > mapper;
dfs( 0, nums, mapper, tmp, ret );

return ret;
}
private:
void dfs( int depth, const std::vector<int>& nums, std::map<int, bool>& visit,
std::vector<int>& tmp, std::vector< std::vector<int> >& ret){

if( depth == nums.size() ) return;
else{
int sz = nums.size();
for( int i = depth; i < sz; ++i )
{
if( depth && (nums[i] < tmp[depth-1]) )
continue;

// 不同试探状态之间彼此不能影响
std::map<int, bool> __visit = visit;
std::vector<int> __tmp = tmp;

// 试探成功
if( !__visit[nums[i]] )
{
__visit[nums[i]] = true;
__tmp.push_back( nums[i] );
ret.push_back( __tmp );

dfs( depth + 1, nums, __visit, __tmp, ret );
}
}
}

}
};


4000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: