算法--找出数组中出现次数超过一半的数
作者:陈太汉
算法--找出数组中出现次数超过一半的数
每当我看到经典的算法题,就怀念高中,感觉很多算法题就是高中的题目,谁叫哥只读了个专科,高数基本相当没学。
有空要看看高数啊,想当年数学那是相当的......
#include <iostream>
using namespace std;
class FindTheOne
{
public:
方法一
第一个想到的方法是见一个二维数组,一维存数组中的数据,二维存这个数出现的次数。出现次数最多的那个数就是要找的那个数
由于某个数出现的次数超过数组长度的一半,所以二维数组的长度只需要这个数组的一半。代码实现如下,
当然这个方法很糟糕,时间复杂度和空间复杂度都比较大,想练手的我还是写了一下。

{
if(NULL==A || len<=0)
{
return ;
}
int (*B)[2]=newint[len/2][2];
B[0][0]=A[0];
B[0][1]=1;
int t=0;
bool notExist=true;
for(int i=1;i<len;++i)
{
for(int j=0;j<t;++j)
{
if(A[i]==B[j][0])
{
B[j][1]++;
notExist=false;
break;
}
}
if(notExist)
{
B[t++][0]=A[i];
}
}
int max=1;
int k=0;
for(int i=0;i<len/2;++i)
{
if(B[i][1]>max)
{
max=B[i][1];
k=i;
}
}
theOne=B[k][0];
}
方法二
将数组排序,最中间的那个数就是您要找的数。
如果出现最多的那个数是最小的,那么1至(n+1)/2都是那个数
如果出现最多的那个数是最大的,那么(n-1)/2至n都是那个数
如果不是最小也不是最大,当这个数由最小慢慢变成最大的最大的数时,你会发现中间的那个数的值是不变的。
综上所述,中间的那个数就是你要找的那个数。
时间复杂度就是你排序用的时间。排序真的不想写了(可以参考《我的另一篇博客》)。大家都知道排序还是相当费时的,当然这个方法还是不太好。
方法三
这个方法借用了别人的思路。
在这里我做一下简单的分析。
这个算法的时间复杂度是O(n),另外用了两个辅助变量。
k用于临时存储数组中的数据,j用于存储某个数出现的次数。
开始时k存储数组中的第一个数,j为0,如果数组出现的数于k相等,则j加1,否则就减1,如果j为0,就把当前数组中的数赋给k
因为指定的数出现的次数大于数组长度的一半,所有j++与j--相抵消之后,最后j的值是大于等于1的,k中存的那个数就是出现最多的那个数。
下面这个算法只适合数组中数组中某个数的出现次数超过数组长度一半的数组,符合题意。

{
if(NULL==A || len<=0)
{
return-1;
}
int k, j=0;
for(int i=0;i<len;++i)
{
if(j==0)
{
k=A[i];
}
if(k==A[i])
{
++j;//有人说++j比j++有先天的优势,不知你是否听说,如果你也听说,有没有想过More Effective C++(C++程序员必看书籍)
}else
{
--j;
}
}
return k;
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库