/*数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}
由于数字2在这个数组中出现了5次,超过数组长度的一半,因此输出2*/
#include <iostream>
using namespace std;
bool g_InvalidInput = false;//定义一个变量标识输入的有效与否
//判断数组是否为有效数组
bool CheckInvalidArray(int *nums, int len)
{
g_InvalidInput = false;
if(nums == NULL || len < 0)
g_InvalidInput = true;
return g_InvalidInput;
}
//判断所取数组是否符合条件
bool CheckMoreThanHalf(int *nums, int len, int number)
{
int times = 0;
int i;
for(i = 0; i < len; ++i)
{
if(nums[i] == number)
times++;
}
bool IsMoreThanHalf = true;
if(times * 2 <= len)
{
g_InvalidInput = true;
IsMoreThanHalf = false;
}
return IsMoreThanHalf;
}
//以快速排序为基础,排序后的数组中间的那个数字就是(如果符合条件)出现次数超过数组长度一半的那个数字
//第一种方法
//=========第二种方法========
//因为若所取数字出现的次数超过一半,则它的次数就超过其它所有数字出现次数的和
int MoreThanHalfNum(int *nums, int len)
{
if(CheckInvalidArray(nums, len))
return 0;
int times = 1;//数字出现的次数,一开始就有一个数故置初值为1而不是0,下面的for循环i从1开始
int result = nums[0];//标识要去的数字
//最后一次把次数设为1的数字就是要找的出现次数超过一半的数字
for(int i = 1; i < len; ++i)
{
if(times == 0)
{
result = nums[i];
times = 1;
}else if(nums[i] == result)
{
times++;
}else
{
times--;
}
}
if(!CheckMoreThanHalf(nums, len, result))
return 0;
return result;
}
//========测试代码===========
void Test(char *TestName, int *nums, int len, int expectednum, bool expectedFlag)
{
if(TestName != NULL)
cout << TestName <<" Begins:" << endl;
int *copy = new int[len]();
for(int i = 0; i < len; ++i)
{
copy[i] = nums[i];
}
// cout << "Solutions for " << TestName << " is:" << endl;
int result = MoreThanHalfNum(nums, len);
if(result == expectednum && g_InvalidInput == expectedFlag)
cout << "Passed" << endl;
else
cout << "Failed!" << endl;
}
//=======测试用例=======
// 存在出现次数超过数组长度一半的数字
void Test1()
{
int nums[] = {1, 2, 3, 2, 2, 2, 5, 4, 2};
Test("Test1", nums, sizeof(nums) / sizeof(int), 2, false);
}
// 不存在出现次数超过数组长度一半的数字
void Test2()
{
int nums[] = {1, 2, 3, 2, 4, 2, 5, 4, 2};
Test("Test2", nums, sizeof(nums) / sizeof(int), 3, true);
}
// 出现次数超过数组长度一半的数字都出现在数组的前半部分
void Test3()
{
int nums[] = {2, 2, 2, 2, 2, 3, 5, 4, 3};
Test("Test3", nums, sizeof(nums) / sizeof(int), 2, false);
}
// 出现次数超过数组长度一半的数字都出现在数组的后半部分
void Test4()
{
int nums[] = {1, 5, 4,3, 2, 2, 2, 2, 2};
Test("Test4", nums, sizeof(nums) / sizeof(int), 2, false);
}
//只有一个元素
void Test5()
{
int nums[] = {1};
Test("Test5", nums, sizeof(nums) / sizeof(int), 1, false);
}
//输入NULL指针
void Test6()
{
Test("Test6", NULL, 0, 0, true);
}
int main()
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
return 0;
}
面试题29:数组中出现次数超过一般的数字
最新推荐文章于 2020-03-07 08:17:02 发布