您的位置:首页 > 其它

在O(n)的时间复杂度内找出数组中出现次数超过了一半的数

2016-04-08 21:28 489 查看
题目来自程序员面试笔试宝典:P303

采用阵地攻守的思想: 第一个数字作为第一个士兵,守阵地;count = 1; 遇到相同元素,count++; 遇到不相同元素,即为敌人,同归于尽,count–;当遇到count为0的情况,又以新的i值作为守阵地的士兵,继续下去,到最后还留在阵地上的士兵,有可能是主元素。 再加一次循环,记录这个士兵的个数看是否大于数组一半即可。

本题O(n)的思想是,定义两个变量temp和count,每次循环时,如果array[i]的值等于temp,则count自增一,如不等并且count>0,则count自减一,若array[i]的值不等于temp并且count不大于0,重新对temp赋值为当前array[i],count赋值为1。

如存在大于一半的数,直接返回temp就是了,但测试数据中有不存在的情况,所以最后又来了一遍校验,检查当前temp值是否出现过一半以上。

Java:

public int MoreThanHalfNum_Solution(int [] array) {
int count = 0;
int temp = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == temp) {
count++;
} else if (count > 0) {
count--;
} else {
temp = array[i];
count = 1;
}
}
//验证
count=0;
for(int i=0;i<array.length;i++){
if(array[i]==temp)
count++;
}
return count > array.length/2 ? temp : 0;
}


C语言:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int aawe(int *num,int len)
{
int candidate=0;
int count=0;
int i;
for(i=0;i<len;i++)
{
if(count==0)
{
candidate=num[i];
count=1;
}
else
{
if(candidate == num[i])
count++;
else
count--;
}
}

count=0;
for(i=0;i<len;i++){
if(num[i]==candidate)
count++;
}
return count > len/2 ? candidate : -1;

}

int main()
{
int c[8]={2,0,70,40,4,24,6,2};
int i;
printf("%d   ",aawe(c,8) );

system("PAUSE");
return 0;
}


引用:

http://www.nowcoder.com/questionTerminal/e8a1b01a2df14cb2b228b30ee6a92163
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: