题目描述
- 统计一个数字在排序数组中出现的次数。例如输入排序数组{1, 2, 3, 3, 3, 3, 4, 5}和数字3,由于3在这个数组中出现了4次,因此输出4。
算法分析
- 对有序数组进行折半查找,找出数字第一个出现的位置和最后一个出现的位置,求出出现的次数。
提交代码:
class Solution {
public:
int GetNumberOfK(vector<int> data, int k) {
if (data.empty())
return 0;
// 折半查找开头
int beg, last;
int start = 0;
int end = data.size() - 1;
while (start < end)
{
int middle = (start + end) / 2;
if (data[middle] < k)
start = middle + 1;
else if(data[middle] > k)
end = middle - 1;
// 相等时
else
{
// 前一位相等
if (middle > 0 && data[middle - 1] == k)
end = middle - 1;
// 前一位已经没有了
else
{
start = middle;
break;
}
}
}
if (data[start] != k)
return 0;
beg = start;
// 折半查找结尾
start = 0;
end = data.size() - 1;
while (start < end)
{
int middle = (start + end) / 2;
if (data[middle] < k)
start = middle + 1;
else if (data[middle] > k)
end = middle - 1;
// 相等时
else
{
// 后一位相等
if (middle < (data.size() - 1) &&
data[middle + 1] == k)
start = middle + 1;
// 后一位已经没有了
else
{
end = middle;
break;
}
}
}
last = end;
return (last - beg + 1);
}
};
测试代码:
// ====================测试代码====================
void Test(const char* testName, vector<int> data, int k, int expected)
{
if (testName != nullptr)
printf("%s begins: ", testName);
Solution s;
int result = s.GetNumberOfK(data, k);
if (result == expected)
printf("Passed.\n");
else
printf("Failed.\n");
}
// 查找的数字出现在数组的中间
void Test1()
{
vector<int> data = { 1, 2, 3, 3, 3, 3, 4, 5 };
Test("Test1", data, 3, 4);
}
// 查找的数组出现在数组的开头
void Test2()
{
vector<int> data = { 3, 3, 3, 3, 4, 5 };
Test("Test2", data, 3, 4);
}
// 查找的数组出现在数组的结尾
void Test3()
{
vector<int> data = { 1, 2, 3, 3, 3, 3 };
Test("Test3", data, 3, 4);
}
// 查找的数字不存在
void Test4()
{
vector<int> data = { 1, 3, 3, 3, 3, 4, 5 };
Test("Test4", data, 2, 0);
}
// 查找的数字比第一个数字还小,不存在
void Test5()
{
vector<int> data = { 1, 3, 3, 3, 3, 4, 5 };
Test("Test5", data, 0, 0);
}
// 查找的数字比最后一个数字还大,不存在
void Test6()
{
vector<int> data = { 1, 3, 3, 3, 3, 4, 5 };
Test("Test6", data, 6, 0);
}
// 数组中的数字从头到尾都是查找的数字
void Test7()
{
vector<int> data = { 3, 3, 3, 3 };
Test("Test7", data, 3, 4);
}
// 数组中的数字从头到尾只有一个重复的数字,不是查找的数字
void Test8()
{
vector<int> data = { 3, 3, 3, 3 };
Test("Test8", data, 4, 0);
}
// 数组中只有一个数字,是查找的数字
void Test9()
{
vector<int> data = { 3 };
Test("Test9", data, 3, 1);
}
// 数组中只有一个数字,不是查找的数字
void Test10()
{
vector<int> data = { 3 };
Test("Test10", data, 4, 0);
}
// 鲁棒性测试,数组空指针
void Test11()
{
Test("Test11", vector<int>(), 0, 0);
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
Test8();
Test9();
Test10();
Test11();
return 0;
}