现在的位置: 首页 > 综合 > 正文

数组中超过N分之一的数字

2018年11月06日 ⁄ 综合 ⁄ 共 1000字 ⁄ 字号 评论关闭

寻找数组中超过一半的元素,这是一道十分经典和普遍的面试题了,实现起来比较容易,只是需要写技巧,将问题扩展就可以衍生到求数组中几个超过N分一的元素,例如找出数组中3个出现次数超过1/4的元素。

/*************************************************************************
        > File Name: morethanharf.c
        > Author: desionwang
        > Mail: wdxin1322@qq.com 
        > Created Time: Tue 29 Oct 2013 05:43:14 PM CST
 ************************************************************************/

#include<stdio.h>

int find(int arr[], int len){
        if(arr == NULL || len <= 0){
                return -1;
        }
        int curr = arr[0];
        int count = 1;
        int i;
        for(i = 1; i < len; i++){
                if(curr == arr[i]){
                        count++;
                }else{
                        count--;
                        if(count < 0){
                                curr = arr[i];
                                count = 1;
                        }
                }
        }
        //check the array is valid or not
        count = 0;
        for(i = 0; i < len ; i++){
                if(arr[i] == curr){
                        count++;
                }
        }
        if(curr * 2 < len){
                return -1;
        }else{
                return curr;
        }
}

这种方法是每次消除两个不同的查询,当两个相邻的查询不同时,相应的计数减一,当相同是加一,当计数减为0时,该元素从被选中去除变为不确定。 

以上是寻找超过二分之一的元素,当寻找两个超过三分之一的元素,或是N-1个超过N分之一的元素时,也同样可以采用这种思想,只要我们每次去掉N个不同的查询就可以,那样剩下的元素就是我们要找的元素。

问题可以这样求解,申请一个大小为N的map,开始遍历数组,如果:

1、遇到一个不在map中的元素,则插入map中,并将value置1

2、遇到一个在map中的元素,则将map中该元素的对应值加1,

当map中的元素个数等于N时,最map中的每个key都减一,key为零的元素直接删除,这样遍历知道数组遍历完,那么map中剩下的key就是所求的元素。

抱歉!评论已关闭.