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