(剑指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;
    }
};
posted @ 2015-07-26 18:16  AndyJee  阅读(2236)  评论(0编辑  收藏  举报