(劍指Offer)面試題38:數字在排序數組中出現的次數


題目:

統計一個數字在排序數組中出現的次數。

思路:

1、順序遍歷

順序掃描一遍數組,統計該數字出現的次數。

時間復雜度:O(n)

2、二分查找

假設我們需要找的數字是k,那么就需要找到數組中的第一個k和最后一個k出現的位置。

如何通過二分查找得到第一個k的位置呢?

取數組中間的數字與k作比較,

如果該數字比k大,那么k只能出現在前半部分,那么下一輪只能在前半部分找;

如果該數字比k小,那么k只能出現在后半部分,那么下一輪只能在后半部分找;

如果該數字等於k,需要判斷這是不是第一個k,如果該數字的前一個數字不是k,那么該數字就是第一個k,否則需要在前半部分繼續尋找第一個k;

尋找最后一個k的方法與尋找第一個k的方法一樣。

代碼:

#include <iostream>

using namespace std;

int getFirstK(int* data,int k,int start,int end){
    while(start<=end){
        int mid=start+((end-start)>>1);
        if(data[mid]==k){
            if((mid>0 && data[mid-1]!=k) || mid==0)
                return mid;
            else
                end=mid-1;
        }
        else if(data[mid]>k)
            end=mid-1;
        else
            start=mid+1;
    }
    return -1;
}

int getLastK(int* data,int length,int k,int start,int end){
    while(start<=end){
        int mid=start+((end-start)>>1);
        if(data[mid]==k){
            if((mid<length-1 && data[mid+1]!=k) || mid==length-1)
                return mid;
            else
                start=mid+1;
        }
        else if(data[mid]<k)
            start=mid+1;
        else
            end=mid-1;
    }
    return -1;
}

int getNumberOfK(int* data,int length,int k){
    if(data==NULL || length<=0)
        return 0;
    int first=getFirstK(data,k,0,length-1);
    int last=getLastK(data,length,k,0,length-1);
    cout<<first<<" "<<last<<endl;
    if(first!=-1 && last!=-1)
        return last-first+1;
    return 0;
}

int main()
{
    int A[]={1,2,3,3,3,3,4,5};
    int len=sizeof(A)/sizeof(A[0]);
    int k=3;
    cout << getNumberOfK(A,len,k) << endl;
    return 0;
}

在線測試OJ:

http://www.nowcoder.com/books/coding-interviews/70610bf967994b22bb1c26f9ae901fa2?rp=2

AC代碼:

class Solution {
public:
    int GetNumberOfK(vector<int> data,int k) {
        int len=data.size();
        if(len<=0)
            return 0;
        int first=getFirstK(data,k,0,len-1);
        int last=getLastK(data,len,k,0,len-1);

        if(first!=-1 && last!=-1)
            return last-first+1;
        return 0;
    }

    int getFirstK(const vector<int> &data,int k,int start,int end){
        int mid;
        while(start<=end){
            mid=start+((end-start)>>1);
            if(data[mid]==k){
                if((mid>0 && data[mid-1]!=k) || mid==0)
                    return mid;
                else
                    end=mid-1;
            }
            else if(data[mid]>k)
                end=mid-1;
            else
                start=mid+1;
        }
        return -1;
    }

    int getLastK(const vector<int> &data,int length,int k,int start,int end){
        int mid;
        while(start<=end){
            mid=start+((end-start)>>1);
            if(data[mid]==k){
                if((mid<length-1 && data[mid+1]!=k) || mid==length-1)
                    return mid;
                else
                    start=mid+1;
            }
            else if(data[mid]>k)
                end=mid-1;
            else
                start=mid+1;
        }
        return -1;
    }
};


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM