方法一:先对数组进行排序,再遍历排序后的数组,统计每个数的次数,出现次数最大的数即为要找的数。
时间复杂度 O(nlogn) + O(n) = O(nlogn)
不需要额外存储空间
方法二:先对数组进行排序,出现次数超过数组长度的一半的数必然是数组中间的那个数
时间复杂度O(nlgn)+ O(1)= O(nlgn)
不需要额外存储空间
方法三:不排序,扫描一遍数组,每次删除两个不同的数,最终得到那个数即为要找的数
时间复杂度O(n)
空间复杂度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;
- }