字符串的全排列
求一个字符串的全排列可以看成是两步。第一步求所有可能出现在第一个第一个位置的字符,即把第一个位置如后面所有的字符交换,这里需要注意:如若字符串中有重复字符,那么重复的字符中只需要其中一个换作首字母。第二步固定第一个字符,求后面所有字符串的全排列,可以这是一个递归操作。
代码示例(以int整形数字为例)
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<vector<int>> res;
if(nums.empty()) return res;
permute(nums,res,nums.size(),0);
return res;
}
void permute(vector<int>& nums,vector<vector<int>>& numlist,int length,int begin)
{
if(begin==length)
{
//递归截止条件,并保存当前排列至结果vector
numlist.push_back(nums);
return;
}
set<int> helper; //用于保存已经出现在首位的字符
for(int i=begin;i<length;++i)
{
if(helper.empty())
helper.insert(nums[i]);
//判断该字符在首位中是否已经出现过,若出现过,则直接跳过
else if(helper.find(nums[i])!=helper.end())
continue;
else
helper.insert(nums[i]);
//将当前字符与首字符交换
int tmp=nums[i];
nums[i]=nums[begin];
nums[begin]=tmp;
//固定首位,递归遍历其余位
permute(nums,numlist,length,begin+1);
//将之前交换的位置换回来
tmp=nums[i];
nums[i]=nums[begin];
nums[begin]=tmp;
}
}
字符串的下一个排列
下一个排列即是按照字典序寻找当前字符串排列的下一个更大的排列,如若不存在下一个更大的排列,则将字符串排列成最小的排列!
首先从字符串尾部开始遍历,找到第一对i 和 ii,使得 i=ii-1 且str[i]
void nextPermutation(vector<int>& nums) {
if(nums.empty()) return;
int end=nums.size()-1;
int i,ii,j;
for(int ii=end;ii>0;--ii)
{
i=ii-1;
//知道满足条件的i和ii
if(nums[i]<nums[ii])
{
for(j=end;j>=0;j--)
{
//找到满足条件的j
if(nums[j]>nums[i])
{
//交换i和j所在位置元素值
swap(nums[i],nums[j]);
//对ii之后所有元素作逆序操作
reverse(nums.begin()+ii,nums.end());
return;
}
}
}
}
//若不满足条件,则对整个数字串作逆序操作
reverse(nums.begin(),nums.end());
return;
}