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

题目来自程序员面试笔试宝典: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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值