面试题26:数组中出现次数超过一半的数字


方法一:先对数组进行排序,再遍历排序后的数组,统计每个数的次数,出现次数最大的数即为要找的数

时间复杂度  O(nlogn) + O(n) = O(nlogn)

不需要额外存储空间

方法二:先对数组进行排序,出现次数超过数组长度的一半的数必然是数组中间的那个数

时间复杂度O(nlgn)+ O(1)= O(nlgn)

不需要额外存储空间

方法三:不排序扫描一遍数组,每次删除两个不同的数,最终得到那个数即为要找的数

时间复杂度On

空间复杂度O(1) 

代码:

 

#include "stdafx.h"
#include <iostream>
using namespace std;

//找出数组中出现次数超过一半的数字,找到则返回true,否则返回fasle
bool FindHalfCountNum(int nArr[], int nLength, int &nNum)
{
	if (nArr==NULL || nLength<=0)
	{
		return false;
	}

    int nCandidate = nArr[0];
	int nCount = 1;
	for (int i=1; i<nLength; i++)
	{
        if (nCount == 0)
        {
			nCandidate = nArr[i];
			nCount = 1;
        }
		else
		{
			if (nCandidate != nArr[i])
			{
				nCount--;
			}
			else
			{
				nCount++;
			}
		}
	}

	nNum = nCandidate;

	nCount = 0;
	for (int j=0; j<nLength; j++)
	{
		if (nArr[j] == nNum)
		{
		   nCount++;
		}
	}

    if (2*nCount > nLength)
    {
		return true;
    }
	else
	{
		cout << "数组中不存在次数超过一半的数字!" << endl;
		return false;
	}
}
int _tmain(int argc, _TCHAR* argv[])
{
	int nNum = 0;
	int nArr1[9] = {1,2,3,2,2,2,5,4,2};
    if (FindHalfCountNum(nArr1, 9, nNum))
    {
		cout << "数组中出现次数超过一半的数字为:" << nNum << endl;
    }

	int nArr2[9] = {1,2,3,2,8,2,5,4,2};
	if (FindHalfCountNum(nArr2, 9, nNum))
	{
		cout << "数组中出现次数超过一半的数字为:" << nNum << endl;
	}

	int nArr3[1] = {1};
	if (FindHalfCountNum(nArr3, 1, nNum))
	{
		cout << "数组中出现次数超过一半的数字为:" << nNum << endl;
	}
	system("pause");
	return 0;
}

运行结果:






原文地址:https://www.cnblogs.com/dyllove98/p/3212467.html