非负整数可重集去重&排序+获得可重集的全排列的几种方法
非负整数可重集O(n)去重并排序
可重集是指元素可重复的集合,对于在一定区间内的正整数集,比如[1,n],我们可以在不不使用任何额外空间(包括不使用O(1)的空间)的情况下,用O(n)的时间复杂度完成集合的去重并排序,这种O(n)的算法,是理想的联机算法。
思路:本质上和桶排序类似,用数组下标来表示存在的元素,数组中的元素作为flag。
对于正整数可重集来说,打标记的方法可以是将元素变负(思考,为什么不是随便赋一个规定的值),负整数依次类推。
对于元素属于[1,n]的集合(n为元素个数),我们可以用下面的代码完成上述操作并取出元素,总时间是O(2n)
void removeDuplicates(int *a,int len){
for(int i=;i<len;i++)
a[abs(a[i])-] = -abs(a[abs(a[i])-]);//如果元素a[i]存在,则将a[abs(a[i])-1] 变负,下标0 ~ n-1 对应1 ~ n
for(int i=;i<len;i++)if(a[i]<)//如果a[i]<0 ,则说明i+1存在 ,取出
printf("%d ",i+);
}
int main(){
int seq[] = {,,,,,,,,};
removeDuplicates(seq,sizeof(seq)/sizeof(int));
return ;
}
获得可重集全排列:
自己玩:
可重集是指元素可重复的集合,可重集的全排列通常可以递归地进行求解。
对于n个元素不重复的集合来说,我们可以递归为:
- 将第k个元素(k=1,2...n)放到集合首部
- 求解剩下n-k个元素的集合的全排列
- 重复1和2,直到集合的元素为空时,打印整个集合
实现的代码(此处是以字符串为例),其中len表示字符串s的长度。注意,这里s必须定义为数组,如果定义为指针,将会引发错误,具体请看我的另一篇博客:C++指针和数组的区别中的情况2
void swap(char &i,char &j){
char t=i;i=j;j=t;
}
void permutation(char s[],int left,int len){
if(left==len)printf("%s\n",s);
else{
for(int k=left;k<len;k++){
if(s[left]!=s[k])swap(s[left],s[k]);
//递归求解n-k个元素的全排列
permutation(s,left+,len);
if(s[left]!=s[k])swap(s[left],s[k]);
}
}
}
需要注意:这种实现不是遵从字典序的实现
当我们需要打印可重集的全排列时,我们只需对递归调用的部分稍作改动
- 重复的情况要保证出现,所以,当left==k的时候,代表第一次递归,此时,应当保留
- 除了1之外,如果s[left]和s[k]仍有相等情况,则不应交换和递归,因为此时若递归,会造成重复
简单修改上述代码,实现如下:
void swap(char &i,char &j){
char t=i;i=j;j=t;
}
void permutation(char s[],int left,int len){
if(left==len)printf("%s\n",s);
else{
for(int k=left;k<len;k++){
//增加了上文的两个判定条件
if(k==left||s[left]!=s[k]){
swap(s[left],s[k]);
permutation(s,left+,len);
swap(s[left],s[k]);
}
}
}
}
同样,这种实现不是遵从字典序的实现。
当然,我们很多时候都需要按照字典序进行排列,说实话,我觉得我是很讨厌手写这个的,毕竟相当的麻烦,所以,就有了下面这个:
黑科技:STL中的next_permutation(s,s+n)
#include<algorithm>
using namespace std;
void permutation(char s[],int len){
sort(s,s+len);//一定要先排序
do{
puts(s);
}while(next_permutation(s,s+len));
}
这是货真价实的字典序的全排列,今天就到这,拜拜~
非负整数可重集去重&排序+获得可重集的全排列的几种方法的更多相关文章
- java中的排序除了冒泡以来, 再给出一种方法, 举例说明
9.5 排序: 有一种排序的方法,非常好理解,详见本题的步骤,先找出最大值和最小值,把最小值打印出来后,把它存在另一个数组b当中,再删除此最小值,之后再来一次找出最小值,打印出最小值以后,再把它存 ...
- 并查集+拓扑排序 赛码 1009 Exploration
题目传送门 /* 题意:无向图和有向图的混合图判环: 官方题解:首先对于所有的无向边,我们使用并查集将两边的点并起来,若一条边未合并之前, 两端的点已经处于同一个集合了,那么说明必定存在可行的环(因为 ...
- List集合对象去重及按属性去重的8种方法-java基础总结系列第六篇
最近在写一些关于java基础的文章,但是我又不想按照教科书的方式去写知识点的文章,因为意义不大.基础知识太多了,如何将这些知识归纳总结,总结出优缺点或者是使用场景才是对知识的升华.所以我更想把java ...
- 分享一种容易理解的js去重排序方法
<script> var arr=[1,8,6,4,88,22,99,4,6,86,5,58,89,5]; //先使用sort()函数去重 var a=arr.sort(function ...
- linux下批量修改存有超大数据量IP文件中的IP内容以及去重排序
作为一个linux的学徒,分享一下自己解决这个小问题的心得,在处理这个问题时使用了一个小技巧感觉很适用,个人发觉linux的终端真滴是非常强大,下面就详细地介绍这个问题以及解决办法吧 问题描述:由于要 ...
- onethink对二维数组结果集进行排序
<?php /** * 对查询结果集进行排序 * @access public * @param array $list 查询结果 * @param string $field 排序的字段名 * ...
- Kettle的集群排序 2——(基于Windows)
5.使用kettle集群模式对相关的数据进行排序 既然,基于Carte服务程序所搭建的集群已经在Spoon中设定好了, 可以首先,先来启动四个节点: "以管理员身份运行"打开 四个 ...
- 在使用Kettle的集群排序中 Carte的设定——(基于Windows)
本片文章主要是关于使用Kettle的UI界面: Spoon来实现基于集群的对数据库中的数据表数据进行排序的试验. 以及在实验过程中所要开启的Carte服务的一些配置文件的设置, 还有基于Windows ...
- for循环去重排序
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
随机推荐
- BZOJ4416 SHOI2013阶乘字符串(状压dp)
当n大到一定程度(>21)时一定无解,并不会证. 如果要取出一个排列,显然应该让每一位在序列中的位置尽量靠前.于是设f[S]表示存在S子集中这些字母所组成的所有排列的最短前缀的长度,枚举当前排列 ...
- [Leetcode] Anagrams 颠倒字母构成词
Given an array of strings, return all groups of strings that are anagrams. Note: All inputs will be ...
- 【COGS 1534】 [NEERC 2004]K小数 &&【COGS 930】 [河南省队2012] 找第k小的数 可持久化01Trie
板子题,只是记得负数加fix最方便 #include <cstdio> ,N=; namespace FIFO { <<],*S=B,*T=B; #define getc() ...
- bzoj2724: [Violet 6]蒲公英 分块 区间众数 论algorithm与vector的正确打开方式
这个,要处理各个数的话得先离散,我用的桶. 我们先把每个块里的和每个块区间的众数找出来,那么在查询的时候,可能成为[l,r]区间的众数的数只有中间区间的众数和两边的数. 证明:若不是这里的数连区间的众 ...
- 淡入淡出效果的js原生实现
淡入淡出效果,在日常项目中经常用到,可惜原生JS没有类似的方法,而有时小的页面并不值得引入一个jQuery库,所以就自己写了一个,已封装, 有用得着的朋友, 可以直接使用. 代码中另附有一个设置元素透 ...
- Codeforces Round #535 (Div. 3) 题解
Codeforces Round #535 (Div. 3) 题目总链接:https://codeforces.com/contest/1108 太懒了啊~好久之前的我现在才更新,赶紧补上吧,不能漏掉 ...
- missing blocks错误
Datanode的日志中看到: 10/12/14 20:10:31 INFO hdfs.DFSClient: Could not obtain block blk_XXXXXXXXXXXXXXXXXX ...
- jquery中的get和post、ajax有关返回值的问题描述
一:前言 今天我就要离开公司回学校准备考试,在走之前,我自己做的一个模块测试除了一些小的bug.问题如下 我在往数据库中插入数据,首先要选择一级菜单,接着会更具一级菜单生成一级菜单的子目录,在选择日期 ...
- 【洛谷 P1337】[JSOI2004]平衡点 / 吊打XXX (模拟退火)
题目链接 正解就算了吧,谁叫我理生化 语数外 政史地都菜呢 模拟退火真玄学,不知道发生了什么就跑出答案了,原理就算了吧,能用(pianfen)就好. 当重物平衡时,势能一定是最小的,于是当我随机出一个 ...
- mongoDB支持的数据类型
下表为MongoDB中常用的几种数据类型. 数据类型 描述 String 字符串.存储数据常用的数据类型.在 MongoDB 中,UTF-8 编码的字符串才是合法的. Integer 整型数值.用于存 ...