剑指offer 数字在排序数组中出现的次数

1.题目

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

来源:剑指offer
链接:https://www.nowcoder.com/practice/70610bf967994b22bb1c26f9ae901fa2?tpId=13&tqId=11190&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

2.我的题解

2.1 rank()方法

rank()方法用于在排序数组中将一个数插入到正确的位置,它可以返回一个数将被放到的“正确的位置”:

  • 如果数组中有此数,将返回该数出现的位置(该数有多个位置的话不确定是哪个位置);
  • 如果数组中没有此数,将返回该数组中大于该数的第一个位置,即该数将被插入的正确的位置。
  • 采用二分法实现。
  • 将参数改成double,用个小技巧可以方便地解决本问题,但是如果原数组是double的那么问题就不好办了。假如数组是{1,1,2,2,3,3},可以查询0.51.5的位置,相减就可以得到1的个数。如果查询13的位置,相减得到的却不是2的个数,而是1,2的总数。同理double型数组不适用。
class Solution {
    int MyRank(vector<int> &data,double i) {
        int l = 0, r = data.size() - 1;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (data[mid] < i)l = mid + 1;
            else if (data[mid] > i)r = mid-1;
            else return mid;
        }
        return l;
    }
public:
    int GetNumberOfK(vector<int> data ,int k) {
        if(data.size()==0)return 0;
        return MyRank(data,k+0.5)-MyRank(data,k-0.5);
    }
};

当然也可以分别获取一个数第一次出现和最后一次出现的位置:

  • 相减加一即为结果;
  • 注意实现时对==情况的不同处理。
  • 要与rank()区分开来,查找索引的方法中找不到返回-1rank()中找不到会返回第一个更大的数的位置。
class Solution {
    int indexFirst(vector<int> &data, int i) {
        int l = 0, r = data.size() - 1;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (data[mid] < i)l = mid + 1;
            else if (data[mid] > i)r = mid - 1;
            else {
                if (mid == l || data[mid - 1] != i)return mid;
                else r = mid - 1;
            }
        }
        return -1;
    }

    int indexLast(vector<int> &data, int i) {
        int l = 0, r = data.size() - 1;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (data[mid] < i)l = mid + 1;
            else if (data[mid] > i)r = mid - 1;
            else {
                if (mid == r || data[mid + 1]!= i)return mid;
                else l = mid + 1;
            }
        }
        return -1;
    }
public:
    int GetNumberOfK(vector<int> data ,int k) {
        int last=indexLast(data,k);
        int first=indexFirst(data,k);
        return last==-1?0:last-first+1;
    }
};

3.别人的题解

3.1 调用upper_bound()和lower_bound()

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        return upper_bound(data.begin(),data.end(),k)
             - lower_bound(data.begin(),data.end(),k);
    }
};

3.2 调用count()

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        return count(data.begin(),data.end(),k);
    }
};

4.总结与反思

(1)indexFirst(),indexLast()中相等情况的处理;
(2)rank()方法,除了用于排序数组中,在二叉树中也有重要应用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值