/*
大小为N的数组A,其主要元素是一个出现次数超过N/2的元素(这样的元素只有一个)
算法概要:
第一步:
找出主要元素的一个候选元(这是难点)。这个候选元是唯一有可能是主要元素的元素。
第二步:
确定是否这个候选元是主要元素。
为了找出候选元,构造第二个数组B。
比较A1和A2,如果它们相等则取其中之一加到数组B中;否则什么都不做;
然后比较A3和A4,按同样的方式处理,其次类推直到读完这个数组,
然后递归的寻找数组B中的候选元,它也是A的候选元. (为什么?)
a, 递归如何终止?
b, 当N是奇数时, 如何处理?
c, 该算法的运行时间是多少?
d, 我们如何避免使用附加数组B?
e, 编写一个程序求解主要元素.
*/
int findMainNum(vector<int> &A)
{
vector<int> B; //候选数组
if(A.empty())
return -1;
else if(A.size() == 1)
return A[0];
for(int i = 0; i < A.size(); i += 2)
if(A[i] == A[i+1] && i+1 < A.size())
B.push_back(A[i]);
int res = findMainNum(B); //递归,将问题规模缩小
if(isMainNum(A,res))
return res == -1? A.back() : res; /* 1*/
else
return -1; //没有找到这样的元素
}
bool isMainNum(vector<int> &A,int res)
{
int count = 0;
int s = res == -1? A.back() : res; //有候选元素使用res,无就使用最后一个元素 /* 2*/
<pre name="code" class="cpp">
for(int i = 0; i < A.size(); i++)
if(A[i] == s) count++; if(count >= A.size()/2 + 1) return true; else return false;}
解释一下 : /* 1*/ 和 /* 2*/
/*
若isMainNum(A,res)为真
则有两种情况:
1.res == -1 ,无候选元素,此时应返回 A[]最后一个元素, s = A.back();
2.res != -1 ,有候选元素,此时应返回 res, s = res;
*/