已知一个整数序列 A = ( a 0 , a 1 , ⋅ ⋅ ⋅ , a n − 1 ) A=(a_0,a_1,···,a_{n-1}) A=(a0,a1,⋅⋅⋅,an−1),其中 0 ≤ a i < n ( 0 ≤ i < n ) 0\leq a_i
给出算法的基本设计思想。代码注释中
根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释
说明你所设计算法的时间复杂度和空间复杂度。
如果存在那么一个数x,他在一个序列中的个数超过整个序列元素数量的一半,那么我们可以使用这样一个思路:设想一下,现在有许多个国家在打仗,然后有一个国家的军队人数比其他所有国家加起来的还多,那么假设每两个士兵交战以后,都会两败俱伤,也就是互相消灭了对方,则那个人数最多的国家一定是可以坚持到最后成为胜利者的,因为最坏的情况下,也就是所有其他国家都只跟他打仗,他也是可以剩下一些士兵的,所以他一定会是胜利者,那么这个胜利者就是主元素
,但是也有可能最后的胜利者是侥幸获胜,因为有可能其他国家会相互厮杀,所以这个国家渔翁得利,那么我们就需要判断一下这个国家原本的实力是否是一定会是胜利者,也就是判断一下他军队人数是不是超过了其他国家人数之和
好的,想到这里,我们应该知道怎么做了,我们只需要将任意两个不一样的数字直接给他抵消掉,那么剩下的最后一个数字可能是胜利者,那么如果它的人数够多,他就是主元素
int Majority(SqlList A){
//假设最终胜利者为A[0]
int winner = A.data[0];
//当前他还有一个士兵
int remain = 1;
for(int i = 1;i 0){
remain--;
}else{
//上一个国家已经没人了,这个国家重新称王
winner = A.data[i];
remain = 1;
}
}
}
if(remain <= 0){
//全部国家灭亡,战争没有胜利者
return -1;
}
//统计战胜国原本人数
int count = 0;
for(int i = 0;i A.length/2){
return winner;
}else{
//侥幸获胜
return -1;
}
}
由于没有开辟额外数组,只是定义了几个变量,所以空间复杂度是O(1),而只有两次循环,且每次循环次数都是N,所以时间复杂度是O(N)