题解 | #数字在升序数组中出现的次数#

数字在升序数组中出现的次数

http://www.nowcoder.com/practice/70610bf967994b22bb1c26f9ae901fa2

一、题目描述

JZ37数字在升序数组中出现的次数
题目大意:找到指定数字在升序数组中出现的次数
注意审题:升序数组

二、算法1(暴力遍历)

算法思路

1.总体思路:直接遍历一次数组,当遇到指定数字时计数即可
2.这种方法虽然直观,但是并没有用上题目中提供的升序这一信息,因此一般不是最优解

代码实现(C++11)

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        int ans = 0;
        for(auto & d : data) ans += d == k;
        return ans;
    }
};

时间复杂度:O(n)
空间复杂度:O(1)

三、算法2(二分法)

算法思路

1.总体思路:由于题目给出的数组是升序的,因此我们可以联系到一种高效的查找算法--二分法
2.对于一段出现在数组中的指定数字,我们只要确定的它出现的第一个位置的下标l,和最后一个位置的下标r,即可得到它的长度为r - l + 1
3.实现细节:需要理解两种常用的二分模板,求大于等于x的第一个数的位置和求小于等于x的第一个数的位置

代码实现(C++11)

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        if(data.empty()) return 0;
        int l, r;
        int i = 0, j = data.size() - 1;
        // 确定l的位置
        while(i < j){
            int mid = i + j >> 1;
            if(data[mid] >= k) j = mid;
            else i = mid + 1;
            }
        l = i;
        if(data[l] < k) l++;    // 若不满足data[l] >= k, l++

        // 确定r的位置
        i = 0, j = data.size() - 1;
        while(i < j){
            int mid = i + j + 1 >> 1;
            if(data[mid] <= k) i = mid;
            else j = mid - 1;
            }
        r = i;
        if(data[r] > k) r--;    // 若不满足data[r] <= k, r--

        return r - l + 1;
    }
};

时间复杂度:O(logn)
空间复杂度:O(1)

全部评论

相关推荐

06-02 15:17
门头沟学院 Java
心爱的idea:怎么会呢 应该是打招呼有问题 问就说实习6个月全国可飞随时到岗
点赞 评论 收藏
分享
能干的三文鱼刷了10...:公司可能有弄嵌入式需要会画pcb的需求,而且pcb能快速直观看出一个人某方面的实力。看看是否有面试资格。问你问题也能ai出来,pcb这东西能作假概率不高
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务