您的位置:首页 > Web前端

【剑指offer系列】 字符串排列___28

2016-04-10 11:06 483 查看
  题目描述:

  输入一个字符串,输入它的所有排列

   

  示例:

  输入:abc

  输出:abc、acb、bac、bca、cab、cba  

  

  代码:   

void permute(string &str,int start){
if(start==str.size())   cout<<str<<endl;

for(int i=start;i<str.size();++i){
swap(str[start],str[i]);
permutate(str,start+1);
swap(str[start],str[i]);
}
}

void permutation(string& str){
if(str.size()<=0)   return;
permute(str,0);
}


  相关题目:

  1、数字的全排列(leetcode 46)

  与字符串的全排列基本相同

  

  代码:  

void getPermutation(vector<vector<int> >& ret,vector<int>& nums,int begin){
if(begin==nums.size()){
ret.push_back(nums);
return;
}
for(int i=begin;i<nums.size();++i){
swap(nums[i],nums[begin]);
getPermutation(ret,nums,begin+1);
swap(nums[i],nums[begin]);
}
}

vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int> > ret;
getPermutation(ret,nums,0);
return ret;
}


  2、含有重复元素的数组的全排列(leetcode 47)

  要求返回的全排列结果无重复

  

  示例:

  输入:[1,1,2]

  输出:[1,1,2], [1,2,1], [2,1,1].

  

  分析:

  由于全排列是递归的将前面的元素与后面的进行交换得到的。

  当含有重复元素时,去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换。

  用编程的话描述就是第i个数与第j个数交换时,要求[i,j)中没有与第j个数相等的数

  

  代码:  

bool noswap(vector<int>& nums,int begin,int cur){    //前面并没有重复数字出现
for(int j=cur-1;j>=begin;--j){
if(nums[j]==nums[cur])  return true;
}
return false;
}
void getPermutation(vector<vector<int> >& ret,vector<int>& nums,int begin){
if(begin==nums.size()){
ret.push_back(nums);
return;
}
for(int i=begin;i<nums.size();++i){
if(noswap(nums,begin,i))    continue; //key step
swap(nums[i],nums[begin]);
getPermutation(ret,nums,begin+1);
swap(nums[i],nums[begin]);
}
}
vector<vector<int>> permuteUnique(vector<int>& nums){
sort(nums.begin(),nums.end());
vector<vector<int> > ret;
getPermutation(ret,nums,0);
return ret;
}


  3、返回第k个排列(leetcode 60)

  输入一个数字n,则数组[1…n]共n!个可能的排列组合。

  输入数字k,返回第k个排列

  

  示例:

  输入n=3,k=4

  123的排列组合情况按顺序共有:

  “123”、”132”、”213”、”231”、”312”、”321”这6种

  k=4,则返回231

  

  分析:

  对于有n个元素的排列组合,可将其分为n组。

  每一组的第一个元素依次为1,2 ……,n,每一组共有(n-1)!种情况。

  以n=3为例,可将排列结果分为3组,每一组有(3-1)!=2种情况。

  第一组以1开始,然后对2,3进行排列组合。

  第二组以2开始,交换1和2的位置,然后对1,3进行排列组合。

  因此对于第k个组合,可先用 k/(n-1)!计算为第几组,确定第一个元素。

  然后递归对剩下的(n-1)个元素进行排列组合,直到将n个元素的位置全都确定。

  

  代码:

string getPermutation(int n, int k) {
if(n==1)    return "1";
vector<int> nums(n,0);
vector<int> base(n,0);
string res;
base[0]=1;
for(int i=1;i<=n;++i){    //base一次存储1!、2!,......,n!,以便得到k/(n-1)!
if(i<n)
base[i]=base[i-1]*i;
nums[i-1]=i;   //所有元素初始序列
}
k=k-1;

while(nums.size()){  //直到将nums中的全部元素都取出
int th=k/base[n-1];  //确定第k个结果在第几组
res+='0'+nums;  //将该元素取出
k=k%base[n-1];      //对剩下n-1个元素递归求取
nums.erase(nums.begin()+th);
--n;
}
return res;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: