【剑指offer系列】 字符串排列___28
2016-04-10 11:06
483 查看
题目描述:
输入一个字符串,输入它的所有排列
示例:
输入:abc
输出:abc、acb、bac、bca、cab、cba
代码:
相关题目:
1、数字的全排列(leetcode 46)
与字符串的全排列基本相同
代码:
2、含有重复元素的数组的全排列(leetcode 47)
要求返回的全排列结果无重复
示例:
输入:[1,1,2]
输出:[1,1,2], [1,2,1], [2,1,1].
分析:
由于全排列是递归的将前面的元素与后面的进行交换得到的。
当含有重复元素时,去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换。
用编程的话描述就是第i个数与第j个数交换时,要求[i,j)中没有与第j个数相等的数
代码:
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个元素的位置全都确定。
代码:
输入一个字符串,输入它的所有排列
示例:
输入: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; } 相关文章推荐
- Bootstrap入门
- javascript原生ajax写法分享
- Javascript实现苹果悬浮虚拟按钮
- javascript之处理Ajax错误
- JSP
- CSS3中文手册基础知识
- 被玩坏了的web前端:前端冷知识
- jQuery之addClass与removeClass使用实例
- json常见样式
- JavaScript图的基本构建
- jQuery实现点击水纹波动动画
- DirectX的Vertex Buffer顶点缓冲的理解和应用
- 如何模块化的组织AngularJS的代码
- 【剑指offer系列】 二叉搜索树与双向链表___27
- error LNK2026: module unsafe for SAFESEH image.
- Jquery form.js文件上传返回JSON数据,在IE下提示下载文件的解决办法,并对返回数据进行正确的解析
- hdoj--5479--Scaena Felix(stack水题)
- node.js学习之路
- ASP.NET MVC Bundles 用法和说明(打包javascript和css)
- JS中使用动态原型模式、寄生构造函数模式、稳妥构造函数模式创建对象