码迷,mamicode.com
首页 > 编程语言 > 详细

38 - 数字在排序数组中的次数

时间:2015-07-29 15:54:46      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:数组

题目描述:
统计一个数字在排序数组中出现的次数。
如输入排序数组 {1,2,3,3,3,3,4,5} 和数字3,由于 3 在数组中出现了 4 次,因此输出 4.


解析:
有序数组中查找一个数可以联想到二分查找
如例子中,要查找3的次数,二分查找,找到3后,它的左右两边可能都有3,因此两边都要查找,如果3在数组中出现了n次,则时间复杂度O(n),二分查找没有起到作用。

假设我们要在数组中查找 k 的次数。因为数组是有序的,那么只要找到数组中的第一个 k 和最后一个 k 就能够确定出现的次数。

  • 那么怎样才能确定是第一个 k 呢?
    二分查找 nums[mid] == k 时,且 mid 的前一项不为 k 。如果前一项仍为 k ,则继续用二分查找向前一半查找第一个 k。
  • 怎样才能确定是最后一个 k 呢?
    二分查找 nums[mid] == k 时,且 mid 的后一项不为 k 。如果后一项仍为 k ,则继续用二分查找向后一半查找最后一个 k。

我们不必查找到每一个 k ,只需查找 2 个 k ,因此时间复杂度 O(logn)

#include <iostream>
using namespace std;
int GetFirstK(int nums[], int start, int end, int k) {
    if (nums == NULL || start > end)
        return -1;
    int mid = (start + end) >> 1;
    int firstK = -1;
    if (nums[mid] == k) {
        if (mid == start || nums[mid-1] != k) // nums[mid] == k, 且 它的前一个不等于 k ,说明是第一个 k
            firstK = mid;
        else
            firstK = GetFirstK(nums, start, mid-1, k);
    } else if (nums[mid] > k) {
        firstK = GetFirstK(nums, start, mid-1, k);
    } else {
        firstK = GetFirstK(nums, mid+1, end, k);
    }
    return firstK;
}
int GetLastK(int nums[], int start, int end, int k) {
    if (nums == NULL || start > end)
        return -1;
    int mid = (start + end) >> 1;
    int lastK = -1;
    if (nums[mid] == k) {
        if (mid == end || nums[mid+1] != k)
            lastK = mid;
        else
            lastK = GetLastK(nums, mid+1, end, k);
    } else if (nums[mid] < k) {
        lastK = GetLastK(nums, mid+1, end, k);
    } else {
        lastK = GetLastK(nums, start, mid-1, k);
    }
    return lastK;
}
int GetCountsOfK(int nums[], int start, int end, int k) {
    if (nums == NULL || start > end)
        return 0;
    int firstK = GetFirstK(nums, start, end, k);
    int lastK = GetLastK(nums, start, end, k);
    if (firstK > -1 && lastK > -1)
        return lastK - firstK + 1;
    return 0;
}
int main() {
    int nums[] = {1,2,3,4,4,4,4,4,5,5,6,9};
    int k = 4;
    cout << GetCountsOfK(nums, 0, sizeof(nums)/sizeof(nums[0])-1, k) << endl;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

38 - 数字在排序数组中的次数

标签:数组

原文地址:http://blog.csdn.net/quzhongxin/article/details/47128457

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!