您的位置:首页 > 其它

LeetCode—**字符串中数字的全排列问题Permutations

2014-08-27 21:56 465 查看

Permutations


Given a collection of numbers, return all possible permutations.For example,
[code][1,2,3]
have the following permutations:
[1,2,3]
,
[1,3,2]
,
[2,1,3]
,
[2,3,1]
,
[3,1,2]
, and
[3,2,1]
.题目主要是为了对数字进行全排列[/code]
想到的办法是将一个数字放到第一位,其余的数字进行全排列,因此需要用递归算法,最后递归返回的vector中的每一个vector,并将第一个数据补充至第一个位置

注意一些vector的函数:

cur.erase(cur.begin()+i); //<删除对应的元素,容器的大小发生了改变

tmp.insert(tmp.begin(), num[i]);

class Solution {
public:
vector<vector<int> > permute(vector<int> &num)
{
vector<int>::size_type N = num.size();
vector<vector<int> > ret;
vector<int> cur;
vector<int> tmp;
if(N == 1)
{
ret.push_back(num);
return ret;
}
vector<vector<int> > post;
for(int i = 0; i < N; i++)
{
cur = num;
cur.erase(cur.begin()+i); //<删除对应的元素,容器的大小发生了改变
post = permute(cur);
for(int j = 0; j < post.size(); j++)
{
tmp = post[j];
tmp.insert(tmp.begin(), num[i]); ret.push_back(tmp);
}
}

return ret;
}
};

在网上还看到很多别的方法:

全排列类似于树结构:

从根节点即为给出的数字的集合

第一层节点为为num[0]和之后的数字一一交换的结果

第二层实在第一层的结果上num[1]和之后的数字一一交换的过程

依次类推,叶子节点就是想要的结果:

举个例子

               123

       123     213      321           i= 0

    123  132 213  231  321  312       i= 1

    123  132 213  231  321  312       i= 2

最后一层则是直接退出

class Solution {
    
    vector<vector<int> > ret;
    int N;
    
public:
    void perm(vector<int> &num, int i){
        if( i == N){
            ret.push_back(num);
        }
        
        for(int j = i; j < N; j++){
            swap(num[i], num[j]);
            perm(num, i + 1);
            swap(num[j], num[i]);
        }
    }

    vector<vector<int> > permute(vector<int> &num) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        N = num.size();
        ret.clear();
        
        perm(num, 0);
        
        return ret;
        
    }
};
stl的algorithm有next permutation的算法的next permutation的算法就是。。。swap + reverse。。。(具体怎么实现全排列还需要自己掌握)
class Solution {
public:
     void nextPermutation(vector<int> &num) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        
        //5,4,7,5,3,2
        //    |     |
        //    i     j
        //5,5,7,4,3,2
        //5,5,2,3,4,7
        int i = num.size()-1;
        while(i > 0 && num[i-1] >= num[i] ){
            i--;
        }
        
        int j = i;
        
        while(j < num.size() && num[j] > num[i-1]) j++;
        
        if(i == 0){
            reverse(num.begin(), num.end());
        }else{
            swap(num[i-1], num[j-1]);
            reverse(num.begin() + i, num.end());
        }
        
        
    }
    
    int factorial(int n){
        return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
    }

    vector<vector<int> > permute(vector<int> &num) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int N = num.size();
        vector<vector<int> > ret;
        
        ret.push_back(num);
        
        for(int i = 1; i < factorial(N); i++){
            nextPermutation(num);
            ret.push_back(num);
        }
        
        return ret;
        
    }
};


补充说明:

erase函数的定义,通过迭代器来删除单个或者范围的元素

iterator erase(
   iterator _Where
);
iterator erase(
   iterator _First,
   iterator _Last
);

remove函数的定义

template<class _FwdIt, class _Ty> inline
    _FwdIt remove(_FwdIt _First, _FwdIt _Last, const _Ty% _Val);
与erase不同的是,remove函数删除元素后并不会改变vector的大小,只是把后面的元素往前移,并返回一个指向vector末尾的新迭代器。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐