面试题53:在排序数组中查找数字

题目描述

统计一个数字在排序数组中出现的次数。

考察点:二分查找的应用;知识迁移能力。

思路:可以直接想到时间复杂度为O(n)的从前到后的遍历方法。

这里采用二分查找法,找到特定出现的k,如果中间的数字比k 大,那么第一次出现的k 只能出现在前半段,如果中间的数字比k小,那么第一次出现k的位置只能在后半段,如果相等的话,如果这个数组前面一个不是k,那么就可以返回下标位置了,如果是k,说明不是第一个出现的k,那么需要接着向前找。同理,找最后一次出现k的位置也是这样二分查找并且递归。

class Solution {
public:
    int getFirstK(vector data, int k, int begin, int end)
    {
        if (begin > end)
            return -1;
        int midIndex = (begin + end) / 2;
        int midData = data[midIndex];//初始中值和下标

        if (midData == k)//三种情况的判断
        {
            if ((midIndex > 0 && data[midIndex - 1] != k) || midIndex == 0)//符合第一个k的条件
            {
                return midIndex;
            }
            else
                end = midIndex - 1;
        }
        else if (midData > k)
        {
            end = midIndex - 1;
        }
        else
            begin = midIndex + 1;
        return getFirstK(data, k, begin, end);//继续递归查找
    }
    int getLastK(vector data, int k, int begin, int end)
    {
        if (begin > end)
            return -1;
        int midIndex = (begin + end) / 2;
        int midData = data[midIndex];
        if (midData == k)
        {
            if ((midIndex != end && data[midIndex + 1] != k) || midIndex == end)
                return midIndex;
            else
                begin = midIndex + 1;
        }
        else if (midData > k)
        {
            end = midIndex - 1;
        }
        else
            begin = midIndex + 1;

        return getLastK(data, k, begin, end);
    }
    int GetNumberOfK(vector data, int k) 
    {
        int number = 0;
        int length = data.size();
        if (!data.empty())
        {
            int first = getFirstK(data, k,0,length-1);
            int last = getLastK(data, k,0, length - 1);

            if (first > -1 && last > -1)//都可以找到其实,一个符合两个都符合
                number= last - first + 1;
        }
        return number;
    }
};

 

 

你可能感兴趣的:(剑指offer)