【算法】[leetcode] permutations的讨论(转载)
原题是找到一组数的全排列
Given a collection of numbers, return all possible permutations.
For example,[1,2,3] have the following permutations:[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1].
vector<vector<int> > permute(vector<int> #
这个题大眼一看就是思路一大坨,这里做一个整理吧
思路1
比较直观的想法就是递归咯~~ 在num中拿出1个数字放在第一个,然后剩下的数字做一个全排列,最早接触这个问题的时候我就是这么写的
- class Solution {
 - public:
 - vector<vector<int> > permute(vector<int> &num) {
 - // Start typing your C/C++ solution below
 - // DO NOT write int main() function
 - int N = num.size();
 - vector<vector<int> > ret;
 - if(N == 1){
 - ret.push_back(num);
 - return ret;
 - }
 - vector<vector<int> > post;
 - vector<int> cur;
 - vector<int> tmp;
 - for(int i = 0; i < N; i++){
 - cur = num;
 - cur.erase(cur.begin()+i);
 - post = permute(cur);
 - for(int j = 0; j < post.size(); j++){
 - tmp = post[j];
 - tmp.insert(tmp.begin(), num[i]);
 - ret.push_back(tmp);
 - }
 - }
 - return ret;
 - }
 - };
 
思路2:
- class Solution {
 - vector<vector<int> > ret;
 - int N;
 - public:
 - void perm(vector<int> &num, int i){
 - if( i == N){
 - ret.push_back(num);
 - }
 - for(int j = i; j < N; j++){
 - swap(num[i], num[j]);
 - perm(num, i + 1);
 - swap(num[j], num[i]);
 - }
 - }
 - vector<vector<int> > permute(vector<int> &num) {
 - // Start typing your C/C++ solution below
 - // DO NOT write int main() function
 - N = num.size();
 - ret.clear();
 - perm(num, 0);
 - return ret;
 - }
 - };
 
思路3
- class Solution {
 - public:
 - void nextPermutation(vector<int> &num) {
 - // Start typing your C/C++ solution below
 - // DO NOT write int main() function
 - //5,4,7,5,3,2
 - // | |
 - // i j
 - //5,5,7,4,3,2
 - //5,5,2,3,4,7
 - int i = num.size()-1;
 - while(i > 0 && num[i-1] >= num[i] ){
 - i--;
 - }
 - int j = i;
 - while(j < num.size() && num[j] > num[i-1]) j++;
 - if(i == 0){
 - reverse(num.begin(), num.end());
 - }else{
 - swap(num[i-1], num[j-1]);
 - reverse(num.begin() + i, num.end());
 - }
 - }
 - int factorial(int n){
 - return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
 - }
 - vector<vector<int> > permute(vector<int> &num) {
 - // Start typing your C/C++ solution below
 - // DO NOT write int main() function
 - int N = num.size();
 - vector<vector<int> > ret;
 - ret.push_back(num);
 - for(int i = 1; i < factorial(N); i++){
 - nextPermutation(num);
 - ret.push_back(num);
 - }
 - return ret;
 - }
 - };
 
思路四
1000 -> 1010 -> 1100 -> 1110 ->1200 -> 1210 ->
2000 -> 2010 -> 2100 -> 2110 ->2200 -> 2210 ->
3000 -> 3010 -> 3100 -> 3110 ->3200 -> 3210
哇哈哈哈,刚好是24个!
然后捏? b0 b1 b2 b3就代表在当前剩下的数字中选择第bi个
哇!好复杂。。。
比如0210
0: 在1234中选择第0个,就是1
2: 在234中选择滴2个,就是4
1: 在23中选择第1个,就是3
0: 在2中选择第0个,就是2
所以0210对应点就素 1432
- class Solution {
 - public:
 - int factorial(int n){
 - return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
 - }
 - void plusp(vector<int> &p, const vector<int> &bound){
 - int i = p.size()-1;
 - while(i >= 0){
 - if(p[i] < bound[i]){
 - p[i]++;
 - break;
 - }else{
 - p[i] = 0;
 - i--;
 - }
 - }
 - }
 - vector<vector<int> > permute(vector<int> &num) {
 - // Start typing your C/C++ solution below
 - // DO NOT write int main() function
 - vector<vector<int> > ret;
 - vector<int> ori_num = num;
 - vector<int> tmp = num;
 - int N = num.size();
 - vector<int> p(N, 0);
 - vector<int> bound = num;
 - for(int i = 0; i < N; i++){
 - bound[i] = N - 1 - i;
 - }
 - for(int i = 0; i < factorial(N); i++){
 - num = ori_num;
 - for(int j = 0; j < N; j++){
 - tmp[j] = num[p[j]];
 - num.erase(num.begin() + p[j]);
 - }
 - ret.push_back(tmp);
 - plusp(p, bound);
 - }
 - return ret;
 - }
 - };
 
关于字典序的补充版本
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example,
[1,1,2]
have the following unique permutations:
[1,1,2] ,  [1,2,1] , and  [2,1,1] .
Permutations 的升级版,依旧是全排列问题,但是 序列中可能会出现重复数字 。
思路:采用字典序的非递归方法。 从字典顺序最小的一种排列开始,每次获得字典序刚好比前一个排列大的排列,直到得到字典序最大的排列时,就得到了所有的结果, 以字符串"abc"为例,"abc"是字典序最小的排列,所有情况按字典序排列为"abc","acb","bac","bca","cba","cab"。
具体步骤为为:
1.字符串进行排序,得到字符串的最小字典序排列(C0C1C2...Cn),Ci<=Ci+1。
2.从后往前,找到一对相邻的升序元素CiCi+1,(Ci<Ci+1),如果遍历完字符串找不到这样的相邻升序对,说明已经达到了字典序最大的全排列
3.从字符串结束位置到位置i遍历,找到比Ci大的元素Cj,交换Cj的位置
4.将Ci+1到Cn所有的字符逆序,这样得到的排列刚好比之前的字典序大(因为转换后Ci+1<Ci+2<...<Cn,为最小字典序)。
5.重复3,4,5过程直到字典序最大。
AC code:
class Solution {
public:
  void swap(int &i,int &j)
  {
    int temp=i;
    i=j;
    j=temp;
  }
  vector<vector<int> > permuteUnique(vector<int> &num)
  {
    vector<vector<int>> res;
    int i,j,n=num.size();
    sort(num.begin(),num.end());
    res.push_back(num);
    while(true)
    {
      for(i=n-2;i>=0;i--)
        if(num[i]<num[i+1])
          break;
      if(i<=-1)
        return res;
      for(j=n-1;j>i;j--)
        if(num[j]>num[i])
          break;
      swap(num[i],num[j]);
      for(int k=i+1;k<(i+1+n)/2;k++)
        swap(num[k],num[n-(k-i)]);
      res.push_back(num);
    }
  }
};
【算法】[leetcode] permutations的讨论(转载)的更多相关文章
- leetcode Permutations II 无重全排列
		
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4051169.html 题目链接:leetcode Permutations II 无重全排 ...
 - 标准差分进化算法matlab程序实现(转载)
		
标准差分进化算法matlab程序实现 自适应差分演化算法方面的Matlab和C++代码及论文 差分进化算法 DE-Differential Evolution matlab练习程序(差异演化DE) [ ...
 - 前端与算法 leetcode 26. 删除排序数组中的重复项
		
目录 # 前端与算法 leetcode 26. 删除排序数组中的重复项 题目描述 概要 提示 解析 算法 # 前端与算法 leetcode 26. 删除排序数组中的重复项 题目描述 26. 删除排序数 ...
 - 前端与算法 leetcode 350. 两个数组的交集 II
		
目录 # 前端与算法 leetcode 350. 两个数组的交集 II 题目描述 概要 提示 解析 解法一:哈希表 解法二:双指针 解法三:暴力法 算法 # 前端与算法 leetcode 350. 两 ...
 - 前端与算法 leetcode 283. 移动零
		
目录 # 前端与算法 leetcode 283. 移动零 题目描述 概要 提示 解析 解法一:暴力法 解法二:双指针法 算法 传入[0,1,0,3,12]的运行结果 执行结果 GitHub仓库 # 前 ...
 - 前端与算法 leetcode 1. 两数之和
		
目录 # 前端与算法 leetcode 1. 两数之和 题目描述 概要 提示 解析 解法一:暴力法 解法二:HashMap法 算法 传入[1, 2], [11, 1, 2, 3, 2]的运行结果 执行 ...
 - 前端与算法 leetcode 48. 旋转图像
		
目录 # 前端与算法 leetcode 48. 旋转图像 题目描述 概要 提示 解析 解法一:转置加翻转 解法二:在单次循环中旋转 4 个矩形 算法 传入测试用例的运行结果 执行结果 GitHub仓库 ...
 - 前端与算法 leetcode 7. 整数反转
		
目录 # 前端与算法 leetcode 7. 整数反转 题目描述 概要 提示 解析 解法 算法 传入测试用例的运行结果 执行结果 GitHub仓库 # 前端与算法 leetcode 7. 整数反转 题 ...
 - 前端与算法 leetcode 8. 字符串转换整数 (atoi)
		
目录 # 前端与算法 leetcode 8. 字符串转换整数 (atoi) 题目描述 概要 提示 解析 解法一:正则 解法二:api 解法二:手搓一个api 算法 传入测试用例的运行结果 执行结果 G ...
 
随机推荐
- SELinux安全方式
			
一.SElinux配置文件 在CentOS 7系统中部署SELinux非常简单,由于SELinux已经作为模块集成到内核中,默认SELinux已经处于激活状态.对管理员来说,更多的是需要配置与管理SE ...
 - vim编辑器操作①
			
Linux文本编辑器: 行编辑器:sed 全屏编辑器:nano,vi/vim 本文主要介绍说明vim编辑器的相关使用: 其有三种模式,即: 编辑模式(默认模式).插入模式(输入模式).末行模式(内置的 ...
 - c# 调用7za.exe执行压缩命令
			
string path7z = $"7zsource\\{project.name}"; string path7zip = $"7z\\{project.name}.7 ...
 - LC327 Count of Range Number
			
这一题,我们使用了分治法. 首先看时间复杂度为o(n^2),比较naïve的方法: 使用一个数组sum[],长度为原数组长度+1,每一个元素sum[i]为原数组中index0~i-1之和,显然当sum ...
 - Centos rpm 卸载
			
参考网址: http://blog.sina.com.cn/s/blog_7d12ba3f01014gxv.html
 - Leetcode581.Shortest Unsorted Continuous Subarray最短无序连续子数组
			
给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序. 你找到的子数组应是最短的,请输出它的长度. 示例 1: 输入: [2, 6, 4, 8, 1 ...
 - c++新特性实验(1)预处理
			
1.参考资料 1.1 C++ C++17 标准文档(正式) : https://www.iso.org/standard/68564.html C++ 标准文档(草案) : ht ...
 - MVVMDemo
			
QueryCommand.cs using System;using System.Collections.Generic;using System.Linq;using System.Text;us ...
 - golang内置函数
 - Django框架Day2------之Template
			
[转]http://www.cnblogs.com/alex3714/articles/5457672.html Django 模版基本语法 >>> from django.temp ...