对于给定的数组,统计出其中最多的元素的值
2017-09-28 22:12
267 查看
/*
问题描述:对于给定的数组,统计出其中最多的元素的值(1,3,5,4,3,3,最多的是3)
说明:对于这个问题,简单的、一般的算法很容易想到(我想到的就是这个)。有点吊的算法使劲想想,应该也能想出来。最牛逼的是第三种算法,能想出来的估计应该算是大牛的级别了。本人绞尽脑汁想出了第一种算法,但男人的第六感告诉我总觉得有更好的方法。所以又查阅了相关资料,整理出来另外两种算法。特记录如下:
算法简要描述:
TheMostNums1: 这是最普通的方法。就是顺序扫描给定的数组,用一个辅助数组记录相同元素的个数,最后在扫描一次辅助数组,找出最大的数,进而找出最多的元素。这种算法的时间复杂度是O(N2),空间的复杂度是O(N)
TheMostNums2:这种算法用了另一种思路。它把每个元素看成一种操作,那么相同的元素对应同一种操作。然后通过分析这种操作的结果,来统计最多的元素。 具体的说,在这里,使用了一个辅助数组每个元素所对应的操作就是往辅助数组中对应的位置+1。最后,统计辅助数组中那个位置被加的最多(元素值最大),那么这个辅助位置对应的下标就是所含有的最多的元素。
这种算法有个小毛病,就是原数组中元素的值不能太大,因为辅助数组个数就是原数组中最大的数。(本程序中就是待定数组的长度)
这个算法的时间复杂度是O(N),空间复杂度取决于申请辅助数组的大小。
TheMostNums3:最牛逼的算法来了。上一种算法是采用了一个辅助数组来映射原数组中元素的操作,那么能不能不用辅助空间实现呢?可以。牛逼的算法直接在原数组上操作,也就是直接映射在原数组上。但是这样就有个问题,你这映射在原数组上,原数组的值不是改变了?那怎么统计相同的元素呢?有什么方法既能够实现映射操作,又能够 保留原来元素的信息呢。这里采用了一种方法,取余。即事先规定好要增加的值大小add_val(在这里不能每次增加1了,至少要大于原数组中最大的值),每次操作就加上add_val。这样原来的值只需要对add_val取余就行。 有点像哈希映射。
详细的可以参考:
是不是挺牛逼的。不过牛逼归牛逼,但是这种算法也有一些问题,就是原数组的中元素最大的值不能大于数组的长度,否则就不够映射了。
这种算法的时间复杂度是O(N),空间复杂度是O(1)。
*/
问题描述:对于给定的数组,统计出其中最多的元素的值(1,3,5,4,3,3,最多的是3)
说明:对于这个问题,简单的、一般的算法很容易想到(我想到的就是这个)。有点吊的算法使劲想想,应该也能想出来。最牛逼的是第三种算法,能想出来的估计应该算是大牛的级别了。本人绞尽脑汁想出了第一种算法,但男人的第六感告诉我总觉得有更好的方法。所以又查阅了相关资料,整理出来另外两种算法。特记录如下:
算法简要描述:
TheMostNums1: 这是最普通的方法。就是顺序扫描给定的数组,用一个辅助数组记录相同元素的个数,最后在扫描一次辅助数组,找出最大的数,进而找出最多的元素。这种算法的时间复杂度是O(N2),空间的复杂度是O(N)
TheMostNums2:这种算法用了另一种思路。它把每个元素看成一种操作,那么相同的元素对应同一种操作。然后通过分析这种操作的结果,来统计最多的元素。 具体的说,在这里,使用了一个辅助数组每个元素所对应的操作就是往辅助数组中对应的位置+1。最后,统计辅助数组中那个位置被加的最多(元素值最大),那么这个辅助位置对应的下标就是所含有的最多的元素。
这种算法有个小毛病,就是原数组中元素的值不能太大,因为辅助数组个数就是原数组中最大的数。(本程序中就是待定数组的长度)
这个算法的时间复杂度是O(N),空间复杂度取决于申请辅助数组的大小。
TheMostNums3:最牛逼的算法来了。上一种算法是采用了一个辅助数组来映射原数组中元素的操作,那么能不能不用辅助空间实现呢?可以。牛逼的算法直接在原数组上操作,也就是直接映射在原数组上。但是这样就有个问题,你这映射在原数组上,原数组的值不是改变了?那怎么统计相同的元素呢?有什么方法既能够实现映射操作,又能够 保留原来元素的信息呢。这里采用了一种方法,取余。即事先规定好要增加的值大小add_val(在这里不能每次增加1了,至少要大于原数组中最大的值),每次操作就加上add_val。这样原来的值只需要对add_val取余就行。 有点像哈希映射。
详细的可以参考:
是不是挺牛逼的。不过牛逼归牛逼,但是这种算法也有一些问题,就是原数组的中元素最大的值不能大于数组的长度,否则就不够映射了。
这种算法的时间复杂度是O(N),空间复杂度是O(1)。
*/
//计算数组中最多的元素(若有多组相同数目的最多元素,则返回首个元素) int TheMostNums1(Sqlist L) { int nums[L.length]; //用来保存每个元素的个数 int the_most_index = 0; //保存最多元素个数个下标 int the_most_nums = 0; //保存最多元素的个数 memset(nums,1,sizeof(int)*L.length); //每个元素初始化为1 //计算每个元素的个数(只有第一个相同元素的下标统计的是正确的,后面相同元素都比前面的少) for(int i = 0;i<L.length;++i) { for(int j = i+1;j<L.length;++j) { if(L.data[i] == L.data[j]) { ++nums[i]; } } } //统计最多元素的下标 for(int i = 0;i<L.length;++i) { if(nums[i]>the_most_nums) { the_most_nums = nums[i]; the_most_index = i; } } return L.data[the_most_index]; }
int TheMostNums2(Sqlist L) { int nums[L.length]; //用来保存每个元素的个数 int the_most_index = 0; //保存最多元素个数个下标 int the_most_nums = 0; //保存最多元素的个数 memset(nums,0,sizeof(int)*L.length); //每个元素初始化为1 for(int i = 0;i<L.length;++i) { if(L.data[i]>L.length || L.data[i]<0) { cout<<"data is wrong!"<<endl; return -1; } else ++nums[L.data[i]]; //把每个元素对应的nums数组的元素+1 } //统计次数 for(int i = 0;i<L.length;++i) { if(the_most_nums<nums[i]) { the_most_nums= nums[i]; the_most_index = i; } } return the_most_index; //返回值最多的下标,即最多的元素 }
int TheMostNums3(Sqlist L) { int add_val = L.length; //每次操作增加的值(只要不小于长度都行) int temp_index = 0; //用作中间换算用 int the_most_index = 0; //用来保存最终的结果 int com_num = 0; //用来保存比较的数 for(int i = 0;i<L.length;++i) { temp_index = L.data[i] % add_val; //将每个元素的值映射到对应位置(这里指的是相同下标) L.data[temp_index] += add_val; //加上每 4000 次要操作的值 } //统计那个元素最多 for(int i = 0;i<L.length;++i) { if(com_num < L.data[i]) { com_num = L.data[i]; the_most_index = i; } } return the_most_index; }
相关文章推荐
- 给定一个整数数组,其中元素的取值范围为0到10000,求其中出现次数最多的数
- 给定一个整数数组,其中元素的取值范围为0到10000,求其中出现次数最多的数
- 说你有一个数组,其中第i个元素是第i天给定股票的价格。设计一个算法来找到最大的利润,最多可以完成两个交易。
- 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法。
- 给定字符串数组,用map的key保存数组中字符串元素,value保存字符串元素出现次数,最后统计个字符串元素出现次数
- 统计数组中出现次数最多的元素并输出
- 随机生成长度为100的数组,数组元素为1到10,统计出现次数最多和最少的元素
- 任意给定一整数数组,求两个元素之差的最大值和数组中出现次数最多的数
- 给定一个长度为N的数组,其中每个元素的取值范围都是1到N。判断数组中是否有重复的数字。(原数组不必保留)
- 对于给定的一个字符串,统计其中数字字符出现的次数。输入数据有多行,第一行是一个整数n,表示测试实例的个数,后面跟着n行,每行包括一个由字母和数字组成的字符串。
- 有一个直方图,用一个整数数组表示,其中每列的宽度为1,求所给直方图包含的最大矩形面积。比如,对于直方图[2,7,9,4],它所包含的最大矩形的面积为14(即[7,9]包涵的7x2的矩形)。给定一个直方图A及它的总宽度n,请返回最大矩形面积。保证直方图宽度小于等于500。保证结果在int范围内。
- 对于一个有序数组,我们通常采用二分查找的方式来定位某一元素,请编写二分查找的算法,在数组中查找指定元素。 给定一个整数数组A及它的大小n,同时给定要查找的元素val,请返回它在数组中的位置(从0开始),若不存在该元素,返回-1。若该元素出现多次,请返回第一次出现的位置。
- [JAVA]给定两个整形数组,并找出其中共同的元素
- 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法
- 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]
- 去除数组中重复项,并统计重复出现次数最多的元素及重复次数
- 对于给定的数组,循环左移p个元素
- 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法
- 给定两颗钻石的编号g1,g2,编号从1开始,同时给定关系数组vector,其中元素为一些二元组,第一个元素为
- 统计一个无序数组中出现次数最多的元素