《劍指offer》——數字在排序數組中出現的次數

由排序數組可以想到使用二分查找法先查找到一個待查的數字,然後再確定該數字第一次出現的位置和最後一次出現的位置,相減即可得到該數字在排序數組中出現的次數。該方法的時間複雜度爲o(logn)

這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述

/*k第一次出現的下標*/
int GetFirstK(vector<int> data, int lo, int hi, int k)
{
    if(hi < lo)//如果k不存在該數組中,則返回-1
        return -1;
    int mi = lo + (hi - lo) / 2;
    if(data[mi] == k)//如果data[mi]等於k
    {
        //如果mi大於0且mi前一個位置上的數字不爲k,或者mi等於0
        if(mi > 0 && data[mi - 1] != k || mi == 0)
            return mi;//mi即爲k第一次出現的下標
        else
            hi = mi - 1;//如果mi前一個位置上的數字仍爲k,則在數組的前半段查找k
    }
    else if(k < data[mi])//如果k在data[mi]之前,則在數組的前半段查找k
        hi = mi - 1;
    else
        lo = mi + 1;//如果k在data[mi]之後,則在數組的後半段查找k
    return GetFirstK(data, lo, hi, k);//繼續查找k第一次出現的下標
}

/*k最後一次出現的下標*/
int GetLastK(vector<int> data, int lo, int hi, int k)
{
    if(hi < lo)//如果k不存在該數組中,則返回-1
        return -1;
    int mi = lo + (hi - lo) / 2;
    if(data[mi] == k)//如果data[mi]等於k
    {
        //如果mi小於數組的最大下標且mi後一個位置上的數字不爲k,或者mi等於數組的最大下標
        if(mi < data.size() - 1 && data[mi + 1] != k || mi == data.size() - 1)
            return mi;//mi即爲k第一次出現的下標
        else
            lo = mi + 1;/如果mi後一個位置上的數字仍爲k,則在數組的後半段查找k
    }
    else if(data[mi] < k)//如果k在data[mi]之後,則在數組的後半段查找
        lo = mi + 1;
    else
        hi = mi - 1;//如果k在data[mi]之前,則在數組的前半段查找
    return GetLastK(data, lo, hi, k);//繼續查找k最後一次出現的下標
}

/*k在數組中出現的次數*/
int GetNumberOfK(vector<int> data ,int k) 
{
    int num = 0;
    if(data.empty())//如果數組爲空,則返回0
        return num;
    int lo = 0, hi = data.size() - 1;
    int fi = GetFirstK(data, lo, hi, k);
    int la = GetLastK(data, lo, hi, k);
    if(fi > -1 && la > -1)//如果k存在數組中,則返回k出現的次數
        num = la - fi + 1;
    return num;
}
發佈了82 篇原創文章 · 獲贊 6 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章