首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

聚合元素的排列与子集

2013-10-27 
集合元素的排列与子集一、集合的排列给定一个集合S,含有n个不重复的元素,输出该集合元素的所有排列,leetcod

集合元素的排列与子集

一、集合的排列

       给定一个集合S,含有n个不重复的元素,输出该集合元素的所有排列,leetcode对应题目为:http://oj.leetcode.com/problems/permutations/。打印所有排列的复杂度为O(n*n!),因为共有n!个不同的排列,打印每个排列的复杂度为O(n)。打印所有的排列一般采用深搜策略,先给出一个常规的方法:

图1排列树形式的解空间

排列树形式的解空间有个规律,就是随着递归深度的增加,每个节点的子节点个数都逐次减一,这也是为什么排列算法的复杂度是O(n!)。

此外,还有一种生成排列的方法,思想不太好懂,下面只给出代码:

图2 子集树形式的解空间

根据上面的分析,我们可以知道求k个元素的子集,我们只需要判断当前已经选择的元素个数,如果已经选择了k个元素,则找到一个符合的子集,无需再遍历子节点。如果尚未选择k个元素,但是已经达到叶节点(n个元素已经判断一遍),我们可以直接返回,这说明此次的遍历没有找到符合的子集。按照这个思路,代码如下:

vector<vector<int> > subsets(vector<int> &S) {sort(S.begin(),S.end());//给定的集合可能未排序                vector<vector<int>> result;                for(int i=0;i<1<<S.size();i++)//每一个二进制数都是一个子集        {            vector<int> r;            for(int j=0;j<S.size();j++)//获得为1的位置            {                if(i>>j&1)                {                    r.push_back(S[j]);                }            }                        result.push_back(r);        }                return result;}

上述三个问题都可以通过深搜完美解决,后两个问题还可以通过位运算解决,不管是深搜还是位运算都有比较相似的模式,希望通过上面的分析,大家能深刻理解深搜和位运算。

热点排行