字符串的排列
题目描述:
输入一个字符串,按字典序打印出该字符串中字符的所有排序。例如输入abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab,cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
题解:
对于这个题目,有多种解法。有函数法、深度优先法、以及函数详解法。
1)函数法:
对于我们需要字符串的全排列,可以根据函数next_permutation得到。
其代码如下:
next_permutation函数的主要功能,就是对字符或者数字进行全排列。其按照字典序产生排列,并且时从当前字典序产生直到最大字典序。
class Solution {
public:
vector<string> Permutation(string str) {
vector<string> res;
if(str.size()==0)
return res;
res.push_back(str);
while(next_permutation(str.begin(),str.end()))
res.push_back(str);
return res;
}
}
2)深度优先搜索:
本质上,此方法运用的是穷举法,例如(abc)。代表了1,2,3位置和a,b,c三个选择。对每个位置不重复选择不同的卡片,返回选择的排列。
根据穷举法,约定,对于三个位置,可以根据先后对三个位置进行选择。
对于第一个位置,我们可以选择1->a,2->b,3->c。当我们位置来到第四个位置时,我们便可以打印出来该字符串。此时我们需要返回位置3,发现除了c没有了其他选择。此时继续返回位置2,当位置2选择时,发现除了b之外还能选择c,那么便对2位置选择c,而3位置便只能选择b。此时,排列新组合(acb)。
同理,不断重复上述,直到重复完毕。
class Solution {
public:
vector<string> res;
string st;
int *mark;
int num;
void dfs_Permutation(string str, int id = 0) {
if (id == num) {//若所有的位置都被标记,即排列完毕
res.push_back(st);
return;
}
for (int i = 0; i < num; i++) {//将所有可能的字符都放置在id位置上
if (mark[i] == 0) {//若该字符还没有使用
st[id] = str[i];//将该字符放置在id位置上
mark[i] = 1;//标记该字符
dfs_Permutation(str, id + 1);//进行下一位置的字符选择
mark[i] = 0;//当作了选择后 回退该字符的标志
}
}
return;
}
vector<string> Permutation(string str) {
if (str.size() == 0)
return res;
num = str.size();
st.resize(num);
mark = new int[num] {0};
dfs_Permutation(str);//进行迭代
sort(res.begin(), res.end());//进行排序
res.erase(unique(res.begin(), res.end()), res.end());//去重
delete[] mark;
return res;
}
};