概述:
大致就是在一个序列中找到一个数字出现次数一半以上的数字
解法:
说不多说,上代码
/**
* date: 2023/9/4
* 整理一下数组中数字有一半以上的情况
* content: 问题一:寻找超过一半的数 (前提是存在)
* content: 问题二:寻找超过一半的数,有就返回那个数,没有就返回无
*/
#include<stdio.h>
// 问题一:寻找超过一半的数 (前提是存在)
//算法思想:逐个抵消,必会出现一半多的那个数
int majorityElement(int *p,int n);
// 问题二: 寻找超过一半的数,不知道有没有的前提
//算法思想: 从前往后扫,标记出一个可能为主元素的元素,可能是真的,那么他count>0;
// 也可能是假的,出现的原因,前面出现的候选主元素被抵消乐,造成后面捡漏。
int Majority(int A[],int n);
int main(){
int a1[] = {0,5,5,3,7,5,5};//定义一个数组,不存在超过一半的数字存在
int a2[] = {0,5,5,3,5,1,5,7};//存在超过一般的数存在数组之中
int n1 = sizeof(a1)/sizeof(a1[0]);//用总数组大小除以第一个数组的字节
int n2 = sizeof(a2)/sizeof(a2[0]);
int number1 = majorityElement(a1,n1);
int number2 = Majority(a2,n2);
printf("第一个数组中某个数字存在的最多的为:%d\n",number1);
printf("第二个数组中某个数字存在的最多的为:%d",number2);
}
int majorityElement(int *p,int n){
int num=0;
int count=0;
for(int i=0;i<n;i++){
if(count==0)
num = p[i];
if(num != p[i])
count--;
else
count++;
}
return num;
}
int Majority(int A[],int n){
int i,c,count=1; //c用来保存候选主元素,count用来计数的
c = A[0]; //设置A[0]为候选主元素
for(i=1;i<n;i++){
if(A[i]==c) //属于则加
count++;
else
if(count>0) //不属于,但是还存在蛮多可以抵消
count--;
else{
c = A[i]; //无法抵消,需要重新更换候选元素
count = 1;
}
}
if(count>0){ //查看候选主元素实际出现的次数 ,辨别是否为真的元素
for(i=count=0;i<n;i++)
if(A[i] == c)
count++;
}
if(count>n/2) return c;
else return -1;
}
总结:
情况1:主要的思想就是相互抵消的原理,超过一半的数字,抵消与之不同的数字之后,必会有多余。
情况2:不确定有没有,先假设有,在去验证真实得次数。
期待下一次的算法分享吧,我是你们的好朋友WQ。