37、数字在排序数组中出现的次数

来源:互联网 发布:iphone 贵吗 知乎 编辑:程序博客网 时间:2024/06/09 14:51

题目描述:统计一个数字在排序数组中出现的次数。

题目一定不是想让我们遍历数组然后数出来,我这回终于不去无聊地尝试这种暴力的方法时间和空间能不能通过了,这是不是有进步2333

然鹅我的方法还是不太简洁,二分查找用的不太好,给自己挖了好大的坑,半天才调出来。。

Ⅰ 我的方法
思路:二分查找,找到等于k的数然后分别在它的前后找连续相同的个数
牛客网只告诉我时间复杂度超出限制,猜测是陷入死循环,把代码搬到vs里慢慢调出来的o(╯□╰)o

代码:

class Solution {public:    int GetNumberOfK(vector<int> data ,int k) {        if (data.size() <= 0)            return 0;        int left = 0, right = data.size() - 1;        int num = 0;        //注意二分查找这里循环条件,如果写成(left < right)会陷入死循环        while (left+1 < right) {            if (data[left] == k || data[right] == k)                break;            int mid = (left + right) / 2;            if (data[mid] < k) {                left = mid;//或者left = mid+1也对            }            else                right = mid;//或者right= mid-1也对        }        //记录找到的这一点的下标        if (data[left] == k) {            num = left;        }        else if (data[right] == k) {            num = right;        }        else {            return 0;        }        //count直接定义为1是因为经历二分查找之后,已经找到一个即num对应的等于k,没找到的情况在上一步的else返回0        //这里定义为1,在向左向右查找时就不计算当前的这一个,避免左右重复        int count = 1;        //向左寻找        int i = num;//不能直接用num自减,因为后面右边还要用到num的值        //不要忘记加if这个判断条件,否则当找到的数就在第一个或最后一个时,直接进入while循环,i作为数组的下标自减或自加就会报错        if (i != 0) {            while (data[--i] == k) {//注意这里是--i不是i--,这样从i的前一个开始计算                count++;            }        }        //向右寻找        i = num;        if (i != data.size() - 1) {            while (data[++i] == k) {                count++;            }        }        return count;    }};

Ⅱ 更机智一点的二分查找
思路:人家的二分查找思路就比我的清晰多了,分别写两个函数找到第一个k值和最后一个k值,最后相减再加一就是k出现的个数。
ps:人家的二分查找用递归调用,看起来比我写的while循环要整齐耶。
代码:

class Solution {public:    int GetNumberOfK(vector<int> data ,int k) {        if(data.size()<=0)            return 0;        int first = getfirstindex(data,k,0,data.size()-1);        int last = getlastindex(data,k,0,data.size()-1);        int number = 0;                if(first > -1 && last > -1)//如果没找到k的话不进if,不要忘记这个判断条件            number = last - first + 1;        return number;    }    int getfirstindex(vector<int> &data ,int k,int start,int end){        if(start>end)            return -1;//如果直到start>end还没找到,说明数组里没有这个数        int mid = (start + end) / 2;        if(data[mid]==k){            if(mid==start || data[mid-1]!=k){//mid是开始的第一个或者mid的前一个不为k,说明mid就是第一个k值                return mid;            }            else{                end = mid -1;            }        }        else{            if(data[mid] < k){                start = mid + 1;            }            else{                end = mid - 1;            }        }        return getfirstindex(data,k,start,end);    }    int getlastindex(vector<int> &data ,int k,int start,int end){        if(start > end)            return -1;        int mid = (start + end) / 2;        if(data[mid]==k){            if(mid==end || data[mid+1]!=k){                return mid;            }            else{                start = mid + 1;            }        }        else{            if(data[mid] < k){                start = mid + 1;            }            else{                end = mid - 1;            }        }        return getlastindex(data,k,start,end);    }};