zoukankan      html  css  js  c++  java
  • 【面试题038】数字在排序数组中出现的次数

    【面试题038】数字在排序数组中出现的次数
    题目:
        统计一个数字在排序数组中出现的次数。例如输入排序数组{1, 2, 3, 3, 3, 3, 4, 5}和数字3,由于3在这个数组中出现了4次,因此输出4。
     
    思路一:
        利用二分查找法,找到这个数字,然后在奇拿后遍历得到这个数字的个数。
    ——时间复杂度是O(n)
     
    思路二:
        可以利用二分查找法,找到等于k的第一个位置和最后一个位置。
        如果中间数字大于k,那么在前半段查找;如果中间数字小于k,那么在后半段查找。
    如果中间数字等于k,而且前面的那个数字不等于k,那么此时中间数字就刚好是第一个k,
    如果中间数字的前一个也是k,那么说第一个k肯定在前半段。下一轮我们依然在前半段查找。
     
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
     
    #include <iostream>

    using namespace std;

    // 找到数组中第一个k的下标。如果数组中不存在k,返回-1
    int GetFirstK(int *data, int length, int k, int start, int end)
    {
        if(start > end)
            return -1;

        int middleIndex = (start + end) / 2;
        int middleData = data[middleIndex];

        if(middleData == k)
        {
            if((middleIndex > 0 && data[middleIndex - 1] != k)
                    || middleIndex == 0)
                return middleIndex;
            else
                end  = middleIndex - 1;
        }
        else if(middleData > k)
            end = middleIndex - 1;
        else
            start = middleIndex + 1;

        return GetFirstK(data, length, k, start, end);
    }

    // 找到数组中最后一个k的下标。如果数组中不存在k,返回-1
    int GetLastK(int *data, int length, int k, int start, int end)
    {
        if(start > end)
            return -1;

        int middleIndex = (start + end) / 2;
        int middleData = data[middleIndex];

        if(middleData == k)
        {
            if((middleIndex < length - 1 && data[middleIndex + 1] != k)
                    || middleIndex == length - 1)
                return middleIndex;
            else
                start  = middleIndex + 1;
        }
        else if(middleData < k)
            start = middleIndex + 1;
        else
            end = middleIndex - 1;

        return GetLastK(data, length, k, start, end);
    }
    int GetNumberOfK(int *data, int length, int k)
    {
        int number = 0;
        if (data != NULL && length > 0)
        {
            int first = GetFirstK(data, length, k, 0, length - 1);
            int last = GetLastK(data, length, k, 0, length - 1);

            if (first > -1 && last > -1)
            {
                number = last - first + 1;
            }
        }
        return number;
    }

    int main()
    {
        int data[] = {12333345};
        int length = sizeof(data) / sizeof(data[0]);
        cout << GetNumberOfK(data, length, 3) << endl;
        return 0;
    }
     
  • 相关阅读:
    我所理解的权限管理系统,纯粹个人规划
    小公司大公司
    找工作神器,提取各大网站有效的招聘信息(前程无忧、智联招聘、猎聘网)
    权限管理系统系列之WCF通信
    权限管理系统系列之序言
    用C#开发的双色球走势图(原创)值得园友拥有(二)接上一篇
    用C#开发的双色球走势图(原创)值得园友拥有
    实例甜点 Unreal Engine 4迷你教程(5)之函数中的静态变量
    实例甜点 Unreal Engine 4迷你教程(4)之用C++实现添加子Widget到VerticalBox中以及ClearChildren
    实例甜点 Unreal Engine 4迷你教程(3)之用C++改变Image小部件的其它属性
  • 原文地址:https://www.cnblogs.com/codemylife/p/3754390.html
Copyright © 2011-2022 走看看