zoukankan      html  css  js  c++  java
  • 数字在排序数组中出现的次数

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

    这个题思路有两种,

    一:直接遍历数组统计,时间复杂度为O(n)略

    二:利用二分法的变种来写

    思路:

    /* 思路, 和普通的二分改变的是当等于给定值需要修改
    我们对数组data进行二分,如果数组中间的数字小于k,说明k应该出现在中间位置的右边;
    如果数组中间的数字大于k,说明k应该出现在中间位置的左边;
    如果数组中间的数字等于k,并且中间位置的前一个数字不等于k,
    说明这个中间数字就是数字k出现的第一个位置。
    */

    代码:

    class Solution {
    public:
        // 二分思路,先找出第一个出现的,在找出最后一个出现的。两个下标相减就是
        // 涉及到二分查找的变种
        int GetNumberOfK(vector<int> data ,int k) {
            int len = data.size();
            if (len <= 0)
                return 0;
            int first = GetFirstK(data, k, 0, len-1);
            int last  = GetLastK(data, k, 0, len-1);
            if (first != -1 && last != -1)
                return last-first + 1;
            else
                return 0;
        }
        //找到第一个出现的位置
        int GetFirstK(vector<int> data, int k, int left, int right)
        {
            while(left <= right)
            {
                int mid = left + (right-left)/2;
                if (data[mid] > k)  //在左半区
                    right = mid -1;
                else if (data[mid] < k) // 在右半区
                    left = mid + 1;
                else
                {
                    if (mid == 0 || data[mid-1] != k)
                        return mid;
                    else  //还要向左半区找
                        right = mid - 1;
                }
            }
            return -1;
        }
        // 找到最后一个出现的位置
        int GetLastK(vector<int> data, int k, int left, int right)
        {
            while(left <= right)
            {
                int mid = left + (right-left)/2;
                if (data[mid] > k)  //在左半区
                    right = mid -1;
                else if (data[mid] < k) // 在右半区
                    left = mid + 1;
                else
                {
                    if (mid == data.size()-1 || data[mid+1] != k)
                        return mid;
                    else  //还要向右半区找
                        left = mid + 1;
                }
            }
            return -1;
        }
    
    };

    含有main函数的

    #include <iostream>
    #include <vector>
    using namespace std;
    class Solution {
    public:
        // 二分思路,先找出第一个出现的,在找出最后一个出现的。两个下标相减就是
        // 涉及到二分查找的变种
        int GetNumberOfK(vector<int> data ,int k) {
            int len = data.size();
            if (len <= 0)
                return 0;
            int first = GetFirstK(data, k, 0, len-1);
            int last  = GetLastK(data, k, 0, len-1);
            if (first != -1 && last != -1)
                return last-first + 1;
            else
                return 0;
        }
        //找到第一个出现的位置
        int GetFirstK(vector<int> data, int k, int left, int right)
        {
            while(left <= right)
            {
                int mid = left + (right-left)/2;
                if (data[mid] > k)  //在左半区
                    right = mid -1;
                else if (data[mid] < k) // 在右半区
                    left = mid + 1;
                else
                {
                    if (mid == 0 || data[mid-1] != k)
                        return mid;
                    else  //还要向左半区找
                        right = mid - 1;
                }
            }
            return -1;
        }
        // 找到最后一个出现的位置
        int GetLastK(vector<int> data, int k, int left, int right)
        {
            while(left <= right)
            {
                int mid = left + (right-left)/2;
                if (data[mid] > k)  //在左半区
                    right = mid -1;
                else if (data[mid] < k) // 在右半区
                    left = mid + 1;
                else
                {
                    if (mid == data.size()-1 || data[mid+1] != k)
                        return mid;
                    else  //还要向右半区找
                        left = mid + 1;
                }
            }
            return -1;
        }
    
    };
    
    
    int main()
    {
        Solution s;
        vector<int> vec = {1,5,5,5,5,6};
        cout << s.GetNumberOfK(vec, 5);
        return 0;
    }
    // 对整个数组遍历
    //    int GetNumberOfK(vector<int> data ,int k) {
    //      int len = data.size();
    //      if (len <= 0)
    //            return 0;
    //      int times = 0;
    //      for (auto it = data.begin(); it != data.end(); it++)
    //      {
    //          if (*it == k)
    //                ++times;
    //      }
    //        return times;
    //    }
    View Code

    二分法变种

    https://www.cnblogs.com/xiaokang01/p/12450117.html

  • 相关阅读:
    RTMP协议Web直播点播系统EasyDSS视频平台解决无法获取指定时间快照问题
    在线教育web无插件点播平台EasyDSS在上传部分点播文件出现无法观看问题如何修复?
    RTMP协议Web直播点播服务平台EasyDSS增加获取录像指定时间的m3u8播放地址
    RTMP协议视频平台EasyDSS编译过程中Go语言异步信息处理设计与实现
    在线课堂web无插件直播点播平台EasyDSS播放指定时间段的录像报404是什么原因?
    推流直播如何通过EasyDSS推流将内网EasyGBS视频流推到公网直播间进行直播?
    RTMP协议视频平台EasyDSS开发中如何通过Go语言 gorm 框架钩子函数精简代码?
    POJ1740 A New Stone Game 博弈论基础题 男人8题
    HDU1847 博弈论 水题
    POJ 2763 Housewife Wind LCA基础题
  • 原文地址:https://www.cnblogs.com/xiaokang01/p/12450147.html
Copyright © 2011-2022 走看看