题目:统计一个数字在排序数组中出现的次数
思路:
1. 从头到尾遍历,超简单,但是应该不符合出题人的意图。
2.因为数组中的数字是整型,所以稍微做一下改变,找 k - 0.5 以及 k + 0.5 的位置(但实际上,数组中是没有 k - 0.5 和 k + 0.5这俩数字的,找 k - 0.5的位置实际上就是第一个 k 出现的位置, 找 k + 0.5 的位置实际上就是第一个k + 1出现的位置)。
例如:对于数组 1 2 2 3,k = 2,找1.5和2.5的位置:
先看1.5:start = 0, end = 3, mid = (0 + 3)/2=1,data[mid] = 2 > 1.5, 则 end = mid - 1 = 0,这时,mid = (0 + 0)/2 = 0, data[mid] = 1 < 1.5, 则start = mid + 1 = 1,这时 start > end, 这个时候的start就是 第一个k出现的位置;
再看2.5:start = 0, end = 3, mid = (0 + 3)/2=1,data[mid] = 2 < 2.5, 则start = mid + 1 = 2,这时,mid = (2 + 3)/2 = 2, data[mid] = 2 < 2.5, 则start = mid + 1 = 3,这时, mid = (3 + 3) / 2 = 3, data[mid] = 3 > 2.5, 则 end = mid - 1 = 2,这时 end < start, 这时的start = 3, 是第一个k + 1,就是3出现的位置;
对于特殊的情况:例如加入数组为1 2 2 2, k = 2, 数组中没有k + 1,即没有3, 那么:自己运行一下可以知道,k + 0.5对应的程序返回的是4,k - 0.5返回的是1,结果就是对的。数组为 2 2 2 3,k = 2的情况类似。
两者相减就是2,即2出现的次数;
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
return Search(data, k + 0.5) - Search(data, k - 0.5);
}
int Search(vector<int> data, double k)
{
int start = 0, end = data.size() - 1;
if(start > end)
return 0;
while(start <= end)
{
int mid = (start + end) >> 1;
if(data[mid] < k)
start = mid + 1;
else
end = mid - 1;
}
return start;
}
};
3. 找到第一个k出现的位置,找到最后一个k出现的位置,两者相减 再加1 就是k出现的次数
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
if(data.empty())
return 0;
int number = 0;
int first = GetFirstIndex(data,k,0,data.size()-1);
int last = GetLastIndex(data,k,0,data.size()-1);
if(first>-1 && last>-1)
number = last - first +1;
return number;
}
int GetFirstIndex(vector<int> &data,int k,int start,int end){
if(start > end)
return -1;
int mid = start+(end-start)/2;
if(data[mid] == k){
if((mid == start) || (data[mid-1] != k))
return mid;
else
end = mid-1;
}
else{
if(data[mid] > k)
end = mid - 1;
else
start = mid + 1;
}
return GetFirstIndex(data,k,start,end);
}
int GetLastIndex(vector<int> &data,int k,int start,int end){
if(start > end)
return -1;
int mid = start+(end-start)/2;
if(data[mid]==k){
if((mid == end) || (data[mid+1] != k))
return mid;
else
start = mid +1;
}
else{
if(data[mid]>k)
end = mid-1;
else
start = mid+1;
}
return GetLastIndex(data,k,start,end);
}
};
4. 利用map
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
if(data.size() <= 0)
return 0;
map<int, int> mp;
for(int i = 0; i < data.size(); ++ i)
++ mp[data[i]];
return mp[k];
}
};