题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
解题思路
1.利用递归的思想解题
在这里分为len步考虑,从第一个单词开始,考虑第一个位置可能出现的所有单词的情况,需要将第一个单词与后面所有位置的单词依次对换位置,也就是说本来是[1, 2, 3]。在这个基础上,对调完了有两个三个情况,[1, 2, 3], [2, 1, 3],[3, 2, 1]
然后在所有的结果中对应求第二个位置的所有的可能的情况,依此递归。
具体代码如下(这里利用的是递归的思想,但是实现的时候摒弃了递归的写法,因为递归是一个速度比较慢的方法,能避则避):
class Solution
{
public:
vector<string> Permutation(string str)
{
//问题在于怎么遍历所有情况,也就是怎么得到一个1到str.size()的排列
//思路:使用递归思想
vector<string> res{};
vector<string> tmp{};
int len = str.size();
if (str.size() == 0) return res;
res.push_back(str);
for (int i = 0; i < len; i++)
{
res = my_func(res, i, len);
}
return res;
}
vector<string> my_func(vector<string> string_set, int idx, int len)
{
vector<string> res{};
string tmp;
for(auto str : string_set)
{
tmp = str;
for (int i = idx; i < len; i++)
{
auto tmp_ch = tmp[idx];
tmp[idx] = tmp[i];
tmp[i] = tmp_ch;
if (find(res.begin(), res.end(), tmp) == res.end() && tmp.size() != 0) res.push_back(tmp);
}
}
return res;
}
};
2.求出所有的可能的路径
如果字符串长度为len,则分len步去做,第n步的作用为找到所有的前n步的可能的情况,也就是说,假设len为4,则第一步的可能为0, 1, 2, 3。第二步的可能就是在第一步的基础上加一步,加的新的步骤必须是之前未出现的元素,例如以0为第一步的情况下,可能的结果为[0, 1],[0, 2],[0,3],根据这样的方法,找到所有的可能的0到len-1的排列,对应的找到其字符串即可(由于可能有字符重复,所以需要考虑重复的情况,在向最终结果导入字符串的时候做一次判断即可)。
具体代码如下:
class Solution
{
vector<vector<int> > paths{};
vector<int> path{};
public:
vector<string> Permutation(string str)
{
//问题在于怎么遍历所有情况,也就是怎么得到一个1到str.size()的排列
//思路:为了得到所有的路径,就化为str.size()个步骤的遍历即可
vector<vector<int> > res{};
vector<string> ans{};
int len = str.size();
for (int i = 0; i < len; i++)
{
res = get_next_set(res, len);
}
string my_str;
for (auto x : res)
{
my_str.clear();
for (auto idx : x)
{
my_str.push_back(str[idx]);
}
if (find(ans.begin(), ans.end(), my_str) == ans.end()) ans.push_back(my_str);
}
return ans;
}
vector<vector<int> > get_next_set(vector<vector<int> > my_set, int len)
{
vector<vector<int> > res{};
vector<int> tmp{};
if (my_set.empty())
{
for (int i = 0; i < len; i++)
{
tmp.clear();
tmp.push_back(i);
res.push_back(tmp);
}
}
else
{
for (auto set : my_set)
{
for (int i = 0; i < len; i++)
{
if (find(set.begin(), set.end(), i) == set.end())
{
tmp = set;
tmp.push_back(i);
res.push_back(tmp);
}
}
}
}
return res;
}
};