數據結構——數組(4)以O(n)時間複雜度,找出數組中出現次數超過一半的數

構建二維數組法:時間和空間複雜度都大,不合題意。
先對數組排序,再取中間元素的方法,最快的排序算法時間複雜度爲O(logn),不合題意。
因此,需要採用其他的一些技巧實現。

方法一:由於目標數字,在數組中出現的次數超過一半。那麼,若每次都取出其中兩個不同的數,最後剩下的必然爲出現次數最多的數。
該方法避免排序,且時間複雜度爲O(n)。

#include <stdlib.h>
#include<iostream>
using namespace std;
int findMostAppear(int *a,int len)
{
    int candidate=0;//候選點,作爲不同數字點對中的參考點
    int count=0;//計數,若被選擇的點和參考候選點一樣,就+1;不一樣,-1;若該計數=0,重新選取候選點
    for(int i=0;i<len;i++)
    {
        //若count爲0,說明沒有候選點,選擇一個候選點
        if(count == 0)
        {
            candidate=a[i];
            count=1;
        }
        //若count不爲0,說明有候選點,判斷a[i]是否和候選點一樣.若一樣,count++;若不一樣,count--,當count減到0的時候,重新選擇候選點
        else
        {
            if(candidate == a[i] )
                count++;
            else
                count--;
        }
    }
    if (count==0)//判斷,若最後兩兩組隊,都沒有了(偶數組),則不存在超多次數一般的數
        return -1;
    else         //else,存在超過一半的數,且就是最後留下的candidate值
        return candidate;//最後剩的數就是要找的超過一半的數
}
int main()
{
    int array[]={1,1,2,2,3,4,1,1};
    int length=sizeof(array)/sizeof(array[0]);
    int i=findMostAppear(array,length);
    cout<<i<<endl;
    getchar();
}

方法二:Hash法。
首先,構建hash_map,然後,遍歷數組,找到出現次數最大的關鍵字和其對應的最大次數,然後判斷該最大次數是否大於等於數組長度的一半,從而確定是否存在次數超過數組一半長度的數。

#include <hash_map>
#include <iostream>
using namespace std;

int findMostAppearHash(int *a,int len,int &val)
{
    hash_map<int,int>myhash;
    for (int i=0;i<len;i++)
    {
        if(     ++myhash[a[i]] >= myhash[val]  )
            val =a[i];
    }

    //判斷最大次數是否大於數組長度一半
    int count = myhash[val];
    if (count>=(len+1)/2)
    {
        cout<<"找到超過數組一半的數"<<endl;   
        return val;
    }
    else
        {
            cout<<"不存在超過數組一半的數"<<endl;
        return -1;
    }
}

int main()
{
    int array[]={1,1,2,2,3,4,1,1};
    int length=sizeof(array)/sizeof(array[0]);
    int value=0;
    int i=findMostAppearHash(array,length,value);
    cout<<i<<endl;
    getchar();
}

方法三:使用兩個變量A和B。
其中A存儲某個數組中的數,B用來計數。開始時候講B初始化爲0,然後遍歷數組。
若當前數與A不同,判斷:若B=0,則A=當前數; 若B>0,則B=B-1。
若當前數與A相同,B計數加1。
遍歷結束,A中存儲的數就是所要找的數。該算法時間複雜度爲O(n), 空間複雜度爲O(1)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章