思路一:
时间复杂度是O(N),只用遍历一次即可。
因为此数字出现的次数超过了整个数组的一半,所以我们挨个遍历,当后面的字符/数字和前面的一样时,则计数器++,不一样计数器–。如果最后计数器大于0,则有超过一半的字符/数字切此数字就是最后一次将计数器++的那个数字,否则则没有。
int MoreHalfNum(int *arr,int len)
{
assert(arr);
if(len < 0)
return -1;
int ret = 0;
int count = 0;
for(int i = 0; i < len ;++i)
{
//如果计数器是空,则把此时i对应下标的数组给ret
if(count == 0)
{
ret = arr[i];
count++;
continue;
}
if(arr[i] == ret)
count++;
else
count --;
}
return ret;
}
思路二:
利用哈希表或者数组统计每个字符出现的次数,找出出现次数超过一半的即可。
template<class T >
T MoreHalfNum(T *arr , int len )
{
map< T, T>mymap;
map< T, T>:: iterator it;
for ( int i = 0; i < len; ++i)
{
it = mymap. find( arr[i]);
//开始的时候map为空,这里相当于插入键值对。
if ( it != mymap.end())
(* it). second++;
else
mymap[ arr[i]] = 1;
}
it = mymap.begin();
while ( it != mymap.end())
{
//这里注意符号优先级的问题
if ((* it). second > ( len / 2))
return (* it). first;
it++;
}
return -1;
}
思路三:
排序一遍,如果此数字出现次数大于整体长度一半,则中间的数字一定是这个数字。(前提是一定有数字出现次数大于长度一半,否则会出错)。
int MoreHalfNum(int *arr,int len)
{
sort(arr,arr+len);
//这里是保证一定有元素出现次数大于一半,如果没有这里可加判断,从中间向后遍历,每一个出现的字符/数字应该相同,若不相同则没有此数字,若都相同,返回arr[len/2]。
for(int i = len/2+1;i<len;++i)
{
if(arr[i] == arr[len/2])
continue;
else
return -1;
}
return arr[len/2];
}