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); } } } };
相关文章推荐
- leetcode 78 Subsets
- Leetcode 78. Subsets
- [leetcode] 78. Subsets
- leetcode 78: Subsets
- leetcode_78——Subsets(基于DFS的递归,基于同质的递推)
- leetcode解题之 77. Combinations&78. Subsets&90. Subsets II java 版(求所有子集)
- leetcode || 78、Subsets
- [LeetCode] 78. Subsets
- Leetcode-78. Subsets
- [LeetCode] 78. Subsets
- Leetcode_78_Subsets
- leetcode[78] Subsets
- LeetCode 78 [Subsets]
- [leetcode-78]subsets(java)
- 【一天一道LeetCode】#78. Subsets
- LeetCode_OJ【78】Subsets
- LeetCode 78. Subsets
- Leetcode 78. Subsets
- 【LeetCode】C# 78、Subsets
- [leetcode 78 & 90, Medium] Subsets I and II