leetcode-47-Permutations II 搜索-剪枝
来源:互联网 发布:使命召唤ol宏数据 编辑:程序博客网 时间:2024/06/03 18:09
问题
题目:[Permutations II]
思路
上来下来个简单的办法,STL套路。
代码
class Solution {public: vector<vector<int>> permuteUnique(vector<int>& nums) { std::vector< std::vector<int> > ret; std::sort( nums.begin(), nums.end() ); do ret.push_back( nums ); while( std::next_permutation( nums.begin(), nums.end() ) ); return ret; }};
思路
当然,利用上一题的做法,上来就对位置全排列。每一次到边界的时候放到集合里面去,去重。思路完全可行。但是没有考虑复杂度,因为位置全排列,长度为n的数组,按位置全排列时n!,这个复杂度非常不可接受。上一道能过是因为,就是那么多,所以好的办法。但是这个题目应该存在明显的剪纸的情形可以优化复杂度。
代码1(TLE)
class Solution {public: vector<vector<int>> permuteUnique(vector<int>& nums) { std::set< std::vector<int> > ret; std::vector< int > arr( nums.size(), int() ); std::set<int> visit; dfs( 0, arr, visit, nums, ret ); std::vector< std::vector<int> > ret1(ret.begin(), ret.end() ); return ret1; }private: void dfs( int depth, std::vector<int>& arr, std::set<int>& visit, const std::vector<int>& nums, std::set< std::vector<int> >& ret ){ int sz = nums.size(); for( int i = 0; i < sz; ++i ) { std::set<int> __visit = visit; if( __visit.find( i ) == __visit.end() ) { arr[depth] = nums[i]; __visit.insert( i ); // insert the location of nums[i] if( sz-1 == depth ) ret.insert( arr ); else dfs( depth+1, arr, __visit, nums, ret ); } } } };
思路
前面已经说了,上来位置全排列。但是不行,dfs复杂度太大。所以,剪枝。剪枝有两个点需要考虑。
- 如果同一层次,当前试探元素前面有重复元素,需要剪枝。[1,1,2],因为同一层次如果元素相同,考虑互相交换后的结果,试探的分枝一样。所以,剪枝。
- 在上面基础之上,剪枝时需要小心一点,如果前面的元素已经出现在上一个层次当中,比如对于第二层的元素,应该在本层的有效元素当中,考虑对重复元素的剪枝。比如[1,1,2],第一层用1展开,第二层,如果只是考虑前面元素是否重复,那么第二个1无法展开,但是第一个1已经出现在上一个层次当中,所以应该避免考虑这些元素。
最后说一个,昨天位置全排列需要小心的一点就是,每层所有元素试探的时候,本质是相互独立的,所以均要使用上一层次的哈希表。
考虑[1,1,1],第一层试探1,第二层试探第二个1,虽然前面出现了1,但是由于第一个1在上一个层次,所以不影响。第二个1展开。还是对于第二层,第三个1,由于第二个1没有在上一层出现过,并且和当前1重复,所以当前试探剪枝。
代码2(剪枝)
class Solution {public: vector<vector<int>> permuteUnique(vector<int>& nums) { int sz = nums.size(); std::vector< std::vector<int> > ret; std::vector< int > arr( sz, int() ); std::set<int> visit; dfs( 0, arr, visit, nums, ret); return ret; }private: void dfs( int depth, std::vector<int>& arr, std::set<int>& visit, const std::vector<int>& nums, std::vector< std::vector<int> >& ret){ int sz = nums.size(); for( int i = 0; i < sz; ++i ) { std::set<int> __visit = visit; int j; for( j = 0; j < i; ++j ) { if( __visit.find(j) != __visit.end() ) // j 在上一层出现过,不影响本层的重复 continue; if( nums[j] == nums[i] ) break; } if( j < i ) continue; if( __visit.find( i ) == __visit.end() ) { arr[depth] = nums[i]; __visit.insert( i ); // insert the location of nums[i] if( sz-1 == depth ) ret.push_back( arr ); else dfs( depth+1, arr, __visit, nums, ret); } } } };
0 0
- leetcode-47-Permutations II 搜索-剪枝
- LeetCode-47-Permutations II(DFS/剪枝)-Medium
- [LeetCode]47. Permutations II && DFS及剪枝
- [leetcode 47] Permutations II
- leetcode || 47、 Permutations II
- leetcode 47 : Permutations II
- leetcode 47: Permutations II
- leetcode 47:Permutations II
- 【leetcode】【47】Permutations II
- LeetCode 47 - Permutations II
- 【LeetCode-47】Permutations II
- LeetCode 47 Permutations II
- Leetcode 47 Permutations II
- Leetcode 47 Permutations II
- LeetCode 47 Permutations II
- Leetcode 47 Permutations II
- LeetCode 46 Permutations + LeetCode 47 Permutations II
- Leetcode 46/47 Permutations, Permutations II
- 第12周项目3-(2)图遍历算法实现、图的广度遍历
- hdu 5996 dingyeye loves stone nim同阶博弈
- C语言总结(1)
- 入门训练 Fibonacci数列
- 每日一练(1)插入排序算法
- leetcode-47-Permutations II 搜索-剪枝
- Struts2类型转换器与拦截器
- 使用IntelliJ IDEA 配置Maven
- c3p0的实现
- 基于谷歌todo-mvp写的例子
- JavaScript学习小结之eval函数和with语句实例详解
- 递归和尾递归
- 第12周项目5-迷宫问题之图深度优先遍历解法
- mysql-proxy mysql主从复制及安装代理服务器