码迷,mamicode.com
首页 > 其他好文 > 详细

leetcode--Permutations

时间:2015-06-08 17:26:10      阅读:110      评论:0      收藏:0      [点我收藏+]

标签:

Given a collection of numbers, return all possible permutations.

For example,
[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].

解题思路:求一串数字的所有排列组合输出

解法一:在num中拿出1个数字放在第一个,然后剩下的数字做一个全排列,用递归实现:代码如下:

class Solution {
public:
    vector<vector<int>> permute(vector<int>& nums) {
        	vector<vector<int>> res;
	vector<vector<int>> temp1;
	int length=nums.size();
	if (length<=1)
	{
		res.push_back(nums);
		return res;
	}
	vector<int> cur;
	vector<int>temp;
	for (int i=0;i<length;i++)
	{
		cur=nums;
		cur.erase(cur.begin()+i);
		temp1=permute(cur);
		for (int j=0;j<temp1.size();j++)
		{
			temp=temp1[j];
			temp.insert(temp.begin(),*(nums.begin()+i));
			res.push_back(temp);
		}
	}
	return res;
    }
};
递归方法不好理解,其中res,length都是每次调用,重新生成的。为了便于理解给出下面递归表示图:
技术分享

解法二:用树结构计算,下面给出(1,2,3)的排列组合的树结构。

技术分享

对于第k层节点来说,就是交换固定了前面 k-1 位,然后分别 swap(k,k), swap(k, k+1) , swap(k, k+2) ...
例如上图中的第2层,固定了第一位(即1),然后分别交换第2,3位。我们用一个三维矩阵Matrix存储上图的树,代码如下:

class Solution {
public:
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int>> res;
	if (nums.size()==1)
	{
		res.push_back(nums);
		return res;
	}
	vector<vector<vector<int>>> maxtrix;
	vector<vector<int>> temp;
	temp.push_back(nums);
	maxtrix.push_back(temp);
	for (int i=0;i<nums.size()-1;i++)
	{
		temp=maxtrix[i];
		vector<vector<int>> temp1;
		for (int j=0;j<temp.size();j++)
		{
			temp1.push_back(temp[j]);
			vector<int> element;
			for (int t=i+1;t<nums.size();t++)
			{
				element=temp[j];
				int tt=element[i];
				element[i]=element[t];
				element[t]=tt;
				temp1.push_back(element);
			}
		}
		maxtrix.push_back(temp1);
	}
	res=maxtrix[maxtrix.size()-1];
	return res;
        
        
    }
};

解法三:

本质就是把N个for改成while的方法,很多把recursive的code改成iterative的code都会用到这样的方法,这个方法在编程之美里面的“电话号码”那一节提到过,参考我的博客http://blog.csdn.net/sinat_24520925/article/details/46413349。
举个例子来说吧
如果我想求1,2,3,4的全排列
偶的思路就是建一个特殊的数,它的进位方法是 3, 2, 1, 0
所以,这个数的++过程就是
0000 -> 0010 -> 0100 -> 0110 ->0200 -> 0210 -> 

1000 -> 1010 -> 1100 -> 1110 ->1200 -> 1210 -> 

2000 -> 2010 -> 2100 -> 2110 ->2200 -> 2210 -> 

3000 -> 3010 -> 3100 -> 3110 ->3200 -> 3210

哇哈哈哈,刚好是24个!

然后捏? b0 b1 b2 b3就代表在当前剩下的数字中选择第bi个

哇!好复杂。。。

比如0210

0: 在1234中选择第0个,就是1

2: 在234中选择滴2个,就是4

1: 在23中选择第1个,就是3

0: 在2中选择第0个,就是2

所以0210对应点就是 1432。

相当于电话号码中0,1,2,3就是电话号码的各个数,1432就是对应的字母。在本题中,我们是要输出一定长度数组的所有排列组合,相当于此数组中的每个值就是一个电话号码,我们要找到,此电话号码对应的所有字母。参考http://blog.csdn.net/sinat_24520925/article/details/46413349的代码,本题的代码如下:

class Solution {
public:
int factorial(int n){
	return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
}
void renew_answer(vector<int> &p, const vector<int> &bound){
	int i = p.size()-1;
	while(i >= 0){
		if(p[i] < bound[i]){
			p[i]++;
			break;
		}else{
			p[i] = 0;
			i--;
		}
	}

}
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int>> res;
        int N=nums.size();
	if (N==1)
	{
		res.push_back(nums);
		return res;
	}
	vector<int> total(N,0);
	for(int i=0;i<N;i++)
	{
	    total[i]=N-1-i;
	}
	vector<int>answer(N,0);
	vector<int>yuan_nums;
	vector<int>temp;
	yuan_nums=nums;
	temp=nums;
	for(int i = 0; i < factorial(N); i++)
	{
	    nums=yuan_nums;
	    for(int j=0;j<N;j++)
	    {
	        temp[j]=nums[answer[j]];
	        nums.erase(nums.begin()+answer[j]);
	    }
	    res.push_back(temp);
	    renew_answer(answer,total);
	}
	return res;
}
};







leetcode--Permutations

标签:

原文地址:http://blog.csdn.net/sinat_24520925/article/details/46413835

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!