面试题29:数组中出现次数超过一般的数字

/*数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值