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


    题目描述:数组中有一个数字的个数超过数组长度的一半,请找出这个数字。例如一个长度为9的数组{1, 2, 3, 2, 2, 2, 5, 4, 2}中数字2出现了两次,所以输出2.

    算法描述:

      解决这道题有几种方法。

      (1)对数组进行排序,然后选取数组的中位数即可,但是我们知道排序最好的最好的时间复杂度就是O(nlgn)。

      (2)下面两种方法是在O(n)的时间内实现的:

        1)基于Partition算法的实现;

          我们知道在排序算法中有一种快速排序就是利用这种方法实现的。它的基本思想是:首先随机找到一个数字,调整数组中数字的顺序,让比这个数字小的数字排在它的左边,比它                  大的排在它的右边;如果下标正好是n/2.则查找成功;如果下标在n/2的左边,则查找它的右边;如果下标在n/2的右边则查找它的左边;递归进行即可;

        

        2)我们知道数组中有一个数字出现的次数超过一半,那么我们可以基于消除的思想去寻找这个数字。如果出现两个不一样的数字那么我们就将两个数字同时消去,继续向下寻找,知道                 最后,剩下的数字就是我们要找的数字。但这是基本的想法,代码实现有自己的思路;

    算法实现:

    O(n)算法1:基于partition

     1 #include<iostream>
     2 using namespace std;
     3  
     4 void swap( int &a, int &b){
     5     int temp = a;
     6     a = b;
     7     b = temp; 
     8 } 
     9 
    10 int partition(int *data, int length, int start, int end){
    11     if(data == NULL || length < 0 || start < 0){
    12         cout<<"the invalid array";
    13     }
    14     
    15     int temp = data[start];
    16     int pos = start;
    17     
    18     for(int i = start + 1; i < end; i++){
    19         if(temp >= data[i]){
    20             ++pos;
    21             swap(data[pos], data[i]);
    22         }
    23     }
    24     
    25     swap(data[start], data[pos]);
    26     return pos;
    27 }
    28 
    29 int MoreHalf(int *data, int length){
    30     if(data == NULL || length < 0){
    31         return 0;
    32     }
    33     
    34     int mid = length >> 1;
    35     int start = 0;
    36     int end = length - 1;
    37     int index = partition(data, length, start, end);
    38     
    39     while(index != mid){
    40         if(index > mid){
    41             end = index - 1;
    42             index = partition(data, length, start, end);
    43         }
    44         else{
    45             start = index + 1;
    46             index = partition(data, length, start, end);
    47         }
    48     }
    49     
    50     return data[mid];    
    51 } 
    52 
    53 int main(){
    54     int str[] = {1, 2, 3, 2, 2, 2, 5, 4, 2};
    55     int len = sizeof(str) / sizeof(int);
    56     int num = MoreHalf(str, len);
    57     
    58     if(num == -1){
    59         cout<<"wrong"<<endl;
    60     }
    61     else{
    62         cout<<"the more than half value of str is: "<<num<<endl;
    63     }
    64     
    65     return 0;
    66 }

     算法2:

     1 #include<iostream>
     2 using namespace std;
     3 
     4 int MoreHalf(int *data, int length){
     5     if(data == NULL || length < 0){
     6         return 0;
     7     }
     8     
     9     int result = data[0];
    10     int times = 1;
    11     for(int i = 1; i < length; ++i){
    12         if(times == 0){
    13             result = data[i];
    14             times == 1;
    15         }
    16         else if(data[i] == result){
    17             times ++;
    18         }
    19         else{
    20             times--;
    21         }
    22     }
    23     
    24     return result;
    25 }
    26 
    27 int main(){
    28     int str[] = {1, 2, 3, 2, 2, 2, 5, 4, 2};
    29     int len = sizeof(str) / sizeof(int);
    30     int num = MoreHalf(str, len);
    31     
    32     if(num == -1){
    33         cout<<"wrong"<<endl;
    34     }
    35     else{
    36         cout<<"the more than half value of str is: "<<num<<endl;
    37     }
    38     
    39     return 0;
    40 }

    参考书籍:

    《剑指offer》

  • 相关阅读:
    Visual Studio中View页面与Js页面用快捷键互相跳转
    使用NLog记录业务日志到数据库
    Js笛卡尔乘积
    多线程更新一个表里面的不同行也可能会死锁
    当请求参数与网站编码不一致时乱码解决方法
    WIN7下vs2010滑轮滚动不正确的解决方法
    VS 2017 代码报错编译正常
    C#表达式树
    .net core 学习 读取配置文件
    .net core 上传文件Demo
  • 原文地址:https://www.cnblogs.com/dormant/p/5395381.html
Copyright © 2020-2023  润新知