• 寻找数组中出现次数超过一半的数字


    【题   目】数组中有一个数字的出现次数超过了该数组长度的一半,找出这个数字。
    
      【思 路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 }
    转载自:http://www.cnblogs.com/python27/archive/2011/12/15/2289534.html
  • 相关阅读:
    C# Winform窗体间传值
    用遍历判断listview是否有重复数据
    asp.net中Webservice的调用实例
    C#中datagridview获取当前行并修改数据
    C#ArrayList的用法
    八步解决ACCESS自动编号问题,SERVER 2000数据库,转换为ACCESS数据库
    SQL Server 2005 中为安装程序增加计数器注册表项值
    我现在在用的.NET数据操作类
    C#中MessageBox用法大全
    C#调用WebService实例和开发
  • 原文地址:https://www.cnblogs.com/leijiangtao/p/4393012.html
Copyright © 2020-2023  润新知