全排列的升级题--全排列和多个数组的组合题

18 篇文章 0 订阅
5 篇文章 0 订阅

        题目:有N个数组,每次从每个数组中取出一个数字,将他们的全排列输出出来。请输出所有的可能。例:三个数组{1,2,3} {4} {5,6},则他们的所有可能为:145的全排列,245的全排列,345的全排列,146的全排列,246的全排列,346的全排列。即:

145,154,415,451,514,541,245,254,452,425,524,542,345,354,435,453,534,543,146,164,416,461,614,641,246,264,42,6,462,624,642,346,364,436,463,634,643。

        这个题,难点在于他是两个题的结合。一个问题是全排列,一个问题是N个数组的遍历规则。所以,解决的方法就是在N个数组的遍历之后,添加上全排列函数。N个数组的遍历,在于模拟他们的遍历方式,如果N是给定的数字,比如3,那么可以使用三层for循环进行这种遍历规则。但是N没有给定,所以采用递归方式来模拟这N层for循环,最后加上全排列。

代码:

#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>
using namespace std;

void show(vector<vector<int>> &ve, vector<int> &flag, int k);
void parti(vector<int> &ve, int begin, int end)
{
	if (begin == end)
	{
		for (int i = 0; i < end; ++i)
			cout << ve[i];
		cout << endl;
	}
	else
	{
		for (int i = begin; i < end; ++i)
		{
			int tmp = ve[begin];
			ve[begin] = ve[i];
			ve[i] = tmp;
			parti(ve, begin + 1, end);
			tmp = ve[begin];
			ve[begin] = ve[i];
			ve[i] = tmp;
		}
	}
}
int main()
{
	vector<vector<int>> ve;
	ve.resize(3);
	for (int i = 1, j = 0; i < 10; i++)
	{
		if (!(i == 5 || i == 6 || i == 7))
			ve[j].push_back(i);
		if (i % 3 == 0)
		{
			j++;
		}
	}
	for (int i = 0; i < 3; ++i)
	{
		copy(ve[i].begin(), ve[i].end(), ostream_iterator<int>(cout, " "));
		cout << endl;
	}
	cout << endl;
	
	//测试使用
	//vector<int> a;
	//a.push_back(1);
	//a.push_back(2);
	//a.push_back(3);
	//parti(a, 0, ve.size());
	//vector<vector<int>> ve1;
	//ve1.resize(4);
	//ve1[0].push_back(1);
	//ve1[0].push_back(2);
	//ve1[1].push_back(3);
	//ve1[1].push_back(4);
	//ve1[2].push_back(5);
	//ve1[3].push_back(6);
	//ve1[3].push_back(7);

	vector<int> flag;
	show(ve, flag, 0);
}
//模拟N个数组的遍历方式
void show(vector<vector<int>> &ve, vector<int> &flag, int k)
{
	if (k < ve.size())
	{
		for (int i = 0; i < ve[k].size(); ++i)
		{
			flag.push_back(ve[k][i]);
			show(ve, flag, k+1);
			flag.pop_back();
		}
	}
	if (flag.size() == ve.size())
	{
		//全排列
		parti(flag, 0, flag.size());
		cout << endl;
	}
	//flag.resize(0);
}

        不过,感觉时间复杂度挺大的,毕竟有两层递归。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值