8.7 无重复字符串的排列组合

     《程序员面试金典》(第六版)习题:仅为记录一下以加强印象,不为商业用途,如有侵权请联系删除。以下源码和解释参考了书中源码以及解释。
     算法一的基本思想是要想获得n个不同字符 c 1 , c 2 , . . . . , c n {c_1,\quad c_2, \quad....,c_n} c1,c2,....,cn的所有排列可以先求得 n − 1 n-1 n1个字符 c 1 , c 2 , . . . . , c n − 1 {c_1,\quad c_2, \quad....,c_{n-1}} c1,c2,....,cn1的所有排列然后将第n个字符 c n c_n cn插入到 n − 1 n-1 n1个字符 c 1 , c 2 , . . . . , c n − 1 {c_1,\quad c_2, \quad....,c_{n-1}} c1,c2,....,cn1的每一个排列的n个位置从而得到n个不同字符的所有排列。

//算法一
vector<string> getPerms(string str)
{
	vector<string> permutations;
	if (str.size() == 0)
	{
		permutations.push_back("");
		return permutations;
	}
	char last = str.back();
	str.pop_back();
	string remainder = str;
	vector<string> words = getPerms(remainder);
	for (string word:words)
	{
		string tempword = word;
		if (word.size() == 0)
		{
			word.push_back(last);
			permutations.push_back(word);
		}
		else
		{ 
			int wordSize= word.size();
		    for (int j = 0; j < wordSize; j++)
		    {
				string word = tempword;
		    	string s = word.insert(j, &last,1);
		    	permutations.push_back(s);
		    }
			tempword.push_back(last);
		    permutations.push_back(tempword);
		}
	}
	return permutations;
}

     算法二的基本思想是要想获得n个不同字符 c 1 , c 2 , . . . . , c n {c_1,\quad c_2, \quad....,c_n} c1,c2,....,cn的所有排列可以先求得n个不同字符中任意 n − 1 n-1 n1个字符 { c 1 , c 2 , . . . . , c n − 1 } \{{c_1,\quad c_2,....,c_{n-1}}\} {c1,c2,....,cn1} { c 1 , c 2 , . . . . , c n − 2 , c n } \{{c_1,\quad c_2, \quad...., c_{n-2}, \quad c_n}\} {c1,c2,....,cn2,cn} { c 1 , c 2 , , c n − 3 , . . . , c n − 1 , c n } \{{c_1,\quad c_2, \quad, c_{n-3},..., c_{n-1}, \quad c_n}\} {c1,c2,,cn3,...,cn1,cn}的所有排列然后将第n个字符 c n c_n cn c n − 1 c_{n-1} cn1 c n − 2 c_{n-2} cn2插入到 n − 1 n-1 n1个字符的每一个排列的第0个位置从而得到n个不同字符的所有排列。

//算法二
vector<string> getPerms(string remainder)
{
	int len = remainder.size();
	vector<string> result;
	if (len == 0)
	{
		result.push_back("");
		return result;
	}
	string tempString = remainder;
	for (int i=0;i<len;i++)
	{
		vector<string> partials = getPerms(remainder.erase(i,1));
		for (string s : partials)
		{
			result.push_back(tempString[i] + s);
		}
		remainder= tempString;
	}
	return result;
}

     算法三是算法二的改进使得递归到基线条件时就已经得到结果。

//算法三
void getPerms(string prefix,string remainder, vector<string> &result)
{
	int len = remainder.size();
	if (len == 0)
	{
		result.push_back(prefix);
	}
	string tempString = remainder;
	for (int i = 0; i < len; i++)
	{
        getPerms(prefix+ tempString[i],remainder.erase(i, 1),result);
		remainder = tempString;
	}
}

vector<string> getPerms(string str)
{
	vector<string> result;
	getPerms("", str, result);
	return result;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qqssss121dfd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值