统计一个数字在排序数组中出现的次数。
这个题思路有两种,
一:直接遍历数组统计,时间复杂度为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; // }