您的位置:首页 > 其它

leetcode-78-Subsets

2017-09-09 13:18 453 查看

问题

题目:[leetcode-78]

思路

按照层次进行枚举即可。主要剪枝的条件。

1. 当前元素之前不能出现过

2. 必须是升序

注意状态恢复。

代码

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

set<int> visited;
int sz = nums.size();
if(!sz) return ret;

dfs( arr, visited, nums, sz, ret );

return ret;
}
private:
void dfs( vector<int>& arr, set<int>& visited, vector<int>& nums, int n, vector<vector<int>>& ret ){
if( arr.size() == n ) return;
else{
for(int i = 0; i < n; ++i){
if( visited.find(nums[i]) != visited.end() ) continue;
int sz = arr.size();
bool legal = true;
for(int k = 0; k < sz; ++k){
if( arr[k] >= nums[i] ){
legal = false;
break;
}
}
if(!legal) continue;

arr.push_back(nums[i]);
visited.insert(nums[i]);

ret.push_back(arr);
dfs( arr, visited, nums, n, ret );

arr.pop_back(); // 状态恢复
visited.erase( nums[i] ); // 状态恢复
}
}
}
};


后记

判断一个数组是否可以两分,正解应该在这里。

背包看起来好像可以解决,但是由于背包要求的是不超过V的条件下,最大的价值。所以它没法精确。

看一道题目:

在n个物品中挑选若干物品装入背包,最多能装多满?假设背包的大小为m,每个物品的大小为A[i]

注意事项

你不可以将物品进行切割。

注意这到题目,这到题目其实并不是标准的背包。此时,它的容量和价值一样。所以,问你在给定V的条件下,最多装多满。此时,价值和容量一样。

如果有4个物品[2, 3, 5, 7]

如果背包的大小为11,可以选择[2, 3, 5]装入背包,最多可以装满10的空间。

如果背包的大小为12,可以选择[2, 3, 7]装入背包,最多可以装满12的空间。

函数需要返回最多能装满的空间大小。

这个题目也可以换个问法:

对于数组[2,3,5,7],如果不超过11,数组中挑出几个数所能形成的最大值应该是多少。

当然,可以采用上面的办法,枚举所有子集,把小于11的拿出来。比以下最大值。

背包的思想也可以使用,在不超过容量11的前提下。获取的最大价值。此时,价值和容量的值是一样的。

但是,如果问数组是否可以等分。以上面的题目为例,那就是是否可以找到一个子集,它的和为8.5。如果是背包,只能用容量做上限。没法精确,这就是问题。

代码2

改进了visted用下标进行标记。

class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<int> arr;
vector<vector<int>> ret;
ret.push_back(arr);
set<int> visited;

dfs( arr, visited, nums, nums.size(), ret );
return ret;
}
private:
void dfs(vector<int>& arr, set<int>& visited, vector<int>& nums, int n, vector<vector<int>>& ret ){
if( arr.size() == n ) return;
else{
for(int i = 0; i < n; ++i){
if( visited.find(i) != visited.end() ) continue;
int sz = arr.size();
bool flag = true;
for( int k = 0; k < sz; ++k ){
if( arr[k] > nums[i] ){ flag = false; break; }
}
if(!flag) continue;

arr.push_back( nums[i] );
visited.insert( i );
ret.push_back(arr);

4000
dfs( arr, visited, nums, n, ret );
arr.pop_back();
visited.erase(i);
}
}
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: