zoukankan      html  css  js  c++  java
  • 【算法22】寻找数组中出现次数超过一半的数字

      【题   目】数组中有一个数字的出现次数超过了该数组长度的一半,找出这个数字。

      【思 路1】由于要寻找的数字的出现次数超过了数组长度的一半,所以如果将该数组排序,那么它的中位数必然是我们要寻找的数字,所以我们的任务就是对该数组进行排序,而性能最好的快速排序的时间复杂度为O(nlogn),我们可以直接借助库函数完成,由于其效率不是很高,所以这里就不再赘述。

      【思 路2】对于一个数组中的元素的次数的统计,最快的查找方法是什么?当然哈希表了!我们能不能建立哈希表呢,稍微思考,我们就可以发现,哈希表只适用于元素的范围比较小的情况,而假设我们的数组是一个整型数组,取值范围跨度太大,所以不适合用哈希表,太浪费空间了。

      等一下,用哈希表的话,我们似乎不需要的条件是:该数字出现次数超过了数组长度的一半?那么多了这个条件,我们能想到什么?这个数字的次数超过了其他所有数字出现的次数之和,所以我们如果用一个key值记录数组中的数字,然后用一个value记录该数字出现的次数,然后累加:继续遍历余下的所有数字,如果和这个数字相等,就把次数加1;如果和这个数字不等,那么就把该数字的次数减1;如果某数字的出现次数为0,那么我们就用下一个数字替换之,然后重置出现次数为1。这样最后剩下的数字肯定就是出现次数超过数组长度一半的数字。好了,讨论到这里我们可以很容易的写出如下的代码:

     1 #include<iostream>
    2 #include<string>
    3 using namespace std;
    4
    5 //全局变量,检查输入是否有效
    6 bool invalidInput = false;
    7
    8 /************************************************************
    9 /* 找出数组中出现次数超过数组长度一半的数字
    10 /************************************************************/
    11 int NumberAppearMoreThanHalf(int* numbers,unsigned int length)
    12 {
    13 if(numbers == NULL || length <= 0)
    14 {
    15 invalidInput = true;
    16 return 0;
    17 }
    18
    19 invalidInput = false;
    20 int key = numbers[0];
    21 unsigned int appearTimes = 1;
    22 for(int i = 1;i < length;++i)
    23 {
    24 if(appearTimes == 0)
    25 {
    26 key = numbers[i];
    27 appearTimes = 1;
    28 }
    29
    30 if(numbers[i] == key)
    31 appearTimes++;
    32 else
    33 appearTimes--;
    34 }
    35
    36 //检验输入的数组是含有满足条件的数字
    37 appearTimes = 0;
    38 for(i = 0; i < length; i++)
    39 {
    40 if(numbers[i] == key)
    41 appearTimes++;
    42 }
    43
    44 if(appearTimes <= length / 2)
    45 {
    46 invalidInput = true;
    47 return 0;
    48 }
    49
    50 return key;
    51 }
    52
    53 int main()
    54 {
    55 cout<<"Enter the length of your array:"<<endl;
    56 int arraylength = 0;
    57 cin>>arraylength;
    58
    59 cout<<"Enter the elements of your array:"<<endl;
    60 int *array = new int[arraylength];
    61 for(int k = 0; k < arraylength;k++)
    62 {
    63 cin>>array[k];
    64 }
    65
    66 cout<<"the number appear more than half length of your array is:"<<endl;
    67 cout<<NumberAppearMoreThanHalf(array,arraylength)<<endl;
    68
    69 delete[] array;
    70
    71 return 0;
    72 }

      运行结果如下:


    References:

    程序员面试题精选100题:http://zhedahht.blog.163.com/blog/static/25411174201085114733349/

    注:

    1)本博客所有的代码环境编译均为win7+VC6。所有代码均经过博主上机调试。

    2)博主python27对本博客文章享有版权,网络转载请注明出处http://www.cnblogs.com/python27/。对解题思路有任何建议,欢迎在评论中告知。


  • 相关阅读:
    1836Alignment
    JS日期格式化
    excle自编公式方法
    excle的公式说明
    小技巧之一 string[]合并
    Nunit的使用小问题
    Ajax中上传文件的方式
    VSS也有BUG?
    SQL Server中将时间型的转为yyyyMMddhhmmss
    给已经存在的PDF文件加水印
  • 原文地址:https://www.cnblogs.com/python27/p/2289534.html
Copyright © 2011-2022 走看看