算法学习——求有重复元素的全排列(递归)

思路:看到这个题目首先能想到的一点就是:①我们要求元素的所有全排列②我们要对求出的全排列去重

第一步:求全排列,这里先讨论对不含重复元素的数组元素进行全排列,用递归方法怎么实现叻

思考这样一种方法:假如我们要求1,2,3,4的全排列,我们可以把1放到前面来,求2,3,4的全排列,之后把2放到前面,求1,3,4的全排列,之后把3放到前面,求1,2,4的全排列,然后把4放到前面来求1,2,3的全排列;这是外层循环,就是遍历每个数,将该数与第一个位置的数交换然后求得余下所有数的全排列,而余下的数的全排列也可以用该种方法求得,当递归到只剩一个数,无法再求其全排列时,递归就有了出口,此时就可以输出了。注意:当我们把1放到前面来,求得剩下所有数的全排列后输出结束,我们需要将1还放回原位置,然后继续将2放到前面来......

void perm(char list[],int k,int m)
{if(k==m)    //当只剩下一个元素时则输出{count++;for(int i=0;i<=m;i++)cout<<list[i];cout<<endl;}for(int i=k;i<=m;i++)  //还有多个元素待排列,递归产生排列{swap(list[k],list[i]);perm(list,k+1,m);swap(list[k],list[i]);}
}

第一步完成后,思考第二步,如何给得到的结果去重呢?

我们求全排列时,是往前提一个数,求余下的数的全排列,假如我们有这样一组数:1,2,3,1,4,如何求全排列呢?实际上只要稍加思考就可以看出,依照上面的方法,两个1分别移到前面求剩下的数的全排列的效果一样,这就产生了重复,所以当1已经在之前求过全排列的话,后面那个1就不用再求了,这样就达到了去重的目的。

我们添加一个条件判断该数是否在之前使用过。

int finish(char list[],int k,int i)
{//第i个元素是否在前面元素[k...i-1]中出现过if(i>k){for(int j=k;j<i;j++)if(list[j]==list[i])return 0;}return 1;
}
void perm(char list[],int k,int m)
{if(k==m)    //当只剩下一个元素时则输出{count++;for(int i=0;i<=m;i++)cout<<list[i];cout<<endl;}for(int i=k;i<=m;i++)  //还有多个元素待排列,递归产生排列{if(finish(list,k,i)) //没有在前面出现过,处理该数{swap(list[k],list[i]);perm(list,k+1,m);swap(list[k],list[i]);}}
}

这样就可以实现带有重复元素的数组求全排列了!

完整代码如下

#include <iostream>
using namespace std;
int count=0;
void swap(char &a,char &b)
{char temp;temp=a;a=b;b=temp;
}
int finish(char list[],int k,int i)
{//第i个元素是否在前面元素[k...i-1]中出现过if(i>k){for(int j=k;j<i;j++)if(list[j]==list[i])return 0;}return 1;
}
void perm(char list[],int k,int m)
{if(k==m)    //当只剩下一个元素时则输出{count++;for(int i=0;i<=m;i++)cout<<list[i];cout<<endl;}for(int i=k;i<=m;i++)  //还有多个元素待排列,递归产生排列{if(finish(list,k,i)){swap(list[k],list[i]);perm(list,k+1,m);swap(list[k],list[i]);}}
}
int main()
{int i,n;cout<<"请输入元素个数: "<<endl;cin>>n;cout<<"请输入待排列的元素: "<<endl;//getchar();char *a=new char[n];for(i=0;i<n;i++)cin>>a[i];cout<<"所有不同排列为: "<<endl;perm(a,0,n-1);cout<<"排列总数为: "<<count<<endl;return 0;
}

最后,加一个容易理解的小视频(这个up讲的太好了,我一个笨蛋都听懂了,供大家学习交流):https://www.bilibili.com/video/BV1dx411S7WR

wish you have a good day!

算法学习——求有重复元素的全排列(递归)相关推荐

  1. 减治求有重复元素的全排列

    求n个元素的全排列的所有解可以用减治法:每次拎出一个数做前缀,对剩下的元素再求全排列,直至只剩一个元素.代码源自<算法分析与设计(王晓东)>,复杂度O(n!) 1 //输出k~m的所有全排 ...

  2. 九章算法面试题54 带重复元素的全排列

    九章算法官网-原文网址 http://www.jiuzhang.com/problem/54/ 题目 给定一个带重复元素的整数集合,求出这个集合中所有元素的全排列.对于集合[1,1,2],其本质不同的 ...

  3. 【模板】 全排列 有重复元素的全排列

    全排列 #include<bits/stdc++.h> using namespace std; int pl[1001]; void print (int n){for(int i=1; ...

  4. 递归法:求n个元素的全排列

    问题:求n个元素的全排列 举例:ABC 其全排列有ABC ACB BAC BCA CAB CBA 法一: 采用分割的思想把第一个元素和后面的其他元素分开思考将问题简单化 public class Qu ...

  5. 7-1 有重复元素的全排列 (10 分)

    7-1 有重复元素的全排列 (10 分) 计算给定的n个数有多少种排列方式,即求全排列(可能出现重复的元素) 输入格式: 第一行输入数字的数量n(n>2),第二行给出每一个数字. 输出格式: 一 ...

  6. 全排列:不含重复元素和含重复元素的全排列

    1.不含重复元素 算法思路: 1.n个元素全排列 = (n-1)个元素的全排列+(另一个元素作为前缀) 2.出口:如果只有一个元素的全排列,则说明已经排完,输出数组: 3.不断将每个元素放在第一个元素 ...

  7. LeetCode Permutations II(有重复元素的全排列)

    问题:给出一个有重复元素的数组,要求输出全排列 思路:先排序,然后使用next_permutation 具体代码参考: https://github.com/wuli2496/OJ/tree/mast ...

  8. 包含重复元素的全排列

    #include<iostream> #include<fstream> #include<algorithm> using namespace std;int n ...

  9. E. Tyler and Strings(组合计数 + 树状数组/线段树)(带重复元素的全排列)

    题目链接 主要思路还是比较好想的,一些细节公式预处理比较难搞- 参考题解 分析 从前往后遍历,如果s[]剩下的数中,s[i] < t[i]则对答案是有贡献的: 贡献就是后面位置[i+1 ~ n] ...

最新文章

  1. java之==和equals区别
  2. 工程和模块的关系以及继承和依赖的概念
  3. ROS 中的camera支持
  4. 我们异口同声说的shooow
  5. 信息学奥赛一本通 1067:整数的个数 | OpenJudge NOI 1.5 11
  6. 96KB存储器的怎么算地址范围_产品条码怎么申请费用
  7. python可以进行矩阵运算吗_python能做MATLAB等价的矩阵运算吗?
  8. QT动态库和静态库使用
  9. 每次发工资条,同事都要随意传看,怎么解决这个问题?
  10. 【ASP.Net MVC】AspNet Mvc一些总结
  11. 前端实践(4)——表单验证(密码重复输入检查)
  12. 中源幼儿园收费管理系统 v5.2.8 是什么
  13. python 输出上三角行列式
  14. 【Python】从堆糖爬取图片Demo
  15. Acwing - 算法基础课 - 笔记(数学知识 · 二)
  16. NYOJ-71:独木舟上的旅行
  17. 创建表的几种方式(语法总结)
  18. linux+kill+进程和线程,什么是程序,进程和线程?三者之间有何关系?
  19. 去掉电影字幕的最好方法
  20. web app 第三方登录-微博登录(二)

热门文章

  1. Linux的linux aarch64和linux x86_64
  2. 优炫数据库百城巡展,成都首站圆满举行
  3. [实践] 创建具有鼠标和键盘同样控制效果的Flash按钮
  4. 万能点位图软件_BoardViewer
  5. 计算机回收站设置大小,2010年职称计算机考试:“回收站”属性的设置
  6. PAT 1040有几个PAT
  7. 【解决】谷歌浏览器闪退/重新安装错误提示0xa0430721
  8. Painter 2019 Essential Training Painter2019年基本训练 Lynda课程中文字幕
  9. 【论文笔记】半监督的多视图学习:Semi-supervised Multi-view Deep Discriminant Representation Learning
  10. Error 263 for command: close audio.mp3 指定的设备未打开,或不被 MCI 所识别。 Failed to close the file: