求数组中重复次数大于数组总数个数一半的数

问题描述:给一个整数数组,求数组中重复出现次数大于数组总个数一半的数

算法思路:1,最容易想到的就是将这个数组排序,然后取出中间的数。最好的排序算法的时间复杂度是O(nlogn).这显然不符合某些公司的要求。

2,遍历一遍数组即找出我们所求的数。在遍历的过程中如果每次删除两个不同的数,那么,在剩下的数的列表中,我们所求的这个数的数量仍然超过总数的一半。

 

int Find(int arr[], int N)
{
    int candidate;
    int nTimes, i;
    for(i = 0; i < N; i++)
    {
       if(nTimes == 0)
       {
            candidate = arr[i];
             nTimes++;
        }
        else
        {
              if(candidate == arr[i])
                    nTimes++;
              else
                    nTime--;
         }
    }

    return candidate;
}

 

这里有一个扩展问题,说一个数组中有三个数,他们在数组中的出现次数都大于1/4,请问如何找出这三个数?

思路是类似的,同样,每次删除4个不同的ID,不影响“那三个ID在剩余ID中出现仍然超过1/4”这一事实,因此我们可以每次删除4个不同的ID,直到剩下3个ID为止。具体编程中怎么体现“删除四个不同ID”这一动作呢?我是这样做的。用candidate[3]记录三个候选ID,用count[3]记录它们的累积次数,然后遍历整个ID列表,每处理一个ID,若与candidate[i]中的某一个相同,则count[i]++,若与三个都不同,则说明找到了四个互不相同的ID,将三个count[i]--,也就相当于“删除了四个不同ID”,若某一个count[i]==0,则更新之。

 
posted @ 2012-08-25 23:32  CobbLiu  阅读(1299)  评论(0)    收藏  举报