数组还有一类问题,就是解决元素出现次数的问题,修改条件,可以有很多问题
数组中出现次数超过一半的数字
问题描述是:有一个数组,在该数组中必定有出现次数超过一般的数字,求出该数字元素。
例如,假设有一数组为a[]={0,2,2,3,2,2,3};,则求出结果为2
第一种方法:可以先排序,由于该数字出现次数超过一半,所以排完序后,该数组的中位数一定是要求的元素。
第二种方法:可以将出现的数字的次数放到数组中,例如数字2,就可以放到a[2],然后a[2]++,表示,出现了一次数字2。所有元素遍历一遍后,最后就出数字次数出现最大的,即是所求元素
第三种方法:非常巧妙,首先我们要利用这个题的前提条件,就是该数组中肯定有该元素,出现次数超过一半。
所以,该元素的次数 减去 其他元素的次数总和 的差值 一定是大于或等于1的,所以利用这一点,我们可以设置两个变量,一个是记录当前元素,另一个是该元素出现次数。
从头开始遍历,如果下一个元素和该元素不一样,则次数-1,如果次数减到了-1,我们就可以设置当前元素为标记元素,次数重置为1,如果元素一样,则次数加一。
为什么计数减到-1,就要重置呢? 因为假设当前元素为a[0],第二个元素为a[1],第三个元素为a[2],这三个元素,如果都不同,说明第一个元素a[0],也就不能成为这三个元素出现次数最多的了,计数再减下去就没有意义了,就重新将第三个元素作为标记元素,接着同样原理去比较
代码如下:
int more_than_half_num(int *a,int size)
{
int flag=a[0];
int count=1;
for(int i=1;i<size;i++)
{
if(a[i]!=flag)
count--;
else if(a[i]==flag)
count++;
if(count==-1)
{
flag=a[i];
count=1;
}
}
return flag;
}
数组中出现次数为一的数字
算法村学习完后,我学到了一种以前没有用过的方法,就是用位运算,这种特别巧妙
规则如上,利用如上规则,有两个一样的就会为0,有单个的就会为单个的那个元素,但是这个题目的前提条件是其他元素只出现两次,所以我们才会用这种 异或位运算。
代码如下:
int find_one_num(int *a,int size)
{
int flag=0;
for(int i=0;i<size;i++)
flag^=a[i];
return flag;
}