• 数字在排序数组中出现的次数


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

    这个题思路有两种,

    一:直接遍历数组统计,时间复杂度为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

  • 相关阅读:
    内网穿透访问Vue项目的时候出现Invalid Host header解决办法
    Java中的super关键字
    java中的Arrays工具类及排序和查找
    Java中方法的覆盖/重写
    java中的数组
    java的内部类概述
    matlab主成分分析PCA
    matlab多元线性回归
    matlab神经网络工具箱
    神经网络(三):前馈神经网络(FNN)
  • 原文地址:https://www.cnblogs.com/xiaokang01/p/12450147.html
Copyright © 2020-2023  润新知