53题在排序数组中查找数字

在排序数组中查找数字

题目描述:

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

思路:既然输入的数组是排序的,那么我们就能很自然的想到利用二分查找算法,但是直接查找,如果该数组全是该数字那么复杂度为O(n),和不用二分查找复杂度相同,所以我们使用二分查找直接差第一个和最后一个k的位置,复杂度为O(logn)。

代码一直接二分查找该数字,复杂度为O(n):

class Solution {
public:
int GetNumber0fkCore(vector<int>&data, int start, int end, int k){
    if (start > end)return 0;
    int mid = (start + end) / 2;
    if (data[mid] == k){
        int result = 1;
        for (int i = mid + 1; i <= end; i++){
            if (data[i] != k)break;
            result++;
        }
        for (int j = mid - 1; j >= start; j--){
            if (data[j] != k)break;
            result++;
        }
        return result;
    }
    if (data[mid] > k){
        return GetNumber0fkCore(data, start, mid - 1, k);
    }
    else{
        return GetNumber0fkCore(data, mid + 1, end, k);
    }
}
int GetNumberOfK(vector<int> data, int k) {
    if (data.empty())return 0;
    return GetNumber0fkCore(data, 0, data.size() - 1, k);
}
};

代码二查找第一个和最后一个k的位置复杂度为O(logn):

class Solution {
public:
int GetFirstK(const vector<int>&data,int start,int end,int k){//采用循环法
    while (start <= end){
        int mid = (start + end) >> 1;
        if (data[mid] > k){
            end = mid - 1;
        }
        else if (data[mid] < k){
            start = mid + 1;
        }
        else if (mid - 1 >= start && data[mid - 1] != k||mid==start){
            return mid;
        }
        else
            end = mid - 1;
    }
    return -1;
}
int GetLastK(const vector<int>&data, int start, int end, int k){//采用递归法
    if (start > end)return -1;
    int mid = (start + end) >> 1;
    if (data[mid] > k)return GetLastK(data, start, mid - 1, k);
    else if (data[mid] < k)return GetLastK(data, mid + 1, end, k);
    else if (data[mid + 1] != k&&mid + 1 <= end||mid==end)return mid;
    else return GetLastK(data, mid+1, end, k);
}
int GetNumberOfK(vector<int> data, int k) {
    if (data.empty())return 0;
    int first = GetFirstK(data, 0, data.size() - 1, k);
    int last = GetLastK(data, 0, data.size() - 1, k);
    if (first != -1 && last != -1){
        return last - first + 1;
    }
    return 0;
}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值