2013-408统考真题-序列主元素

线性表

2013年统考真题

已知一个整数序列 A = ( a 0 , a 1 , ⋅ ⋅ ⋅ , a n − 1 ) A=(a_0,a_1,···,a_{n-1}) A=(a0,a1,⋅⋅⋅,an1),其中 0 ≤ a i < n ( 0 ≤ i < n ) 0\leq a_i0ai<n(0i<n)。若存在 a p 1 = a p 2 = ⋅ ⋅ ⋅ = a p m = x a_{p_1}=a_{p_2}=···=a_{p_m}=x ap1=ap2=⋅⋅⋅=apm=x m > n 2    ( 0 ≤ p k < n , 1 ≤ k ≤ m ) m>\frac{n}{2}\ \ (0\leq p_km>2n  (0pk<n,1km),则称x为A的主元素。例如 A = ( 0 , 5 , 5 , 3 , 5 , 7 , 5 , 5 ) A=(0,5,5,3,5,7,5,5) A=(0,5,5,3,5,7,5,5),则5为主元素;又如 A = ( 0 , 5 , 5 , 3 , 5 , 1 , 5 , 7 ) A=(0,5,5,3,5,1,5,7) A=(0,5,5,3,5,1,5,7),则A中没有主元素。假设A中的n个元素保存在一个一维数组中,请设计一个尽可能高效的算法,找出A的主元素。若存在主元素,则输出该元素;否则输出-1。要求:

  1. 给出算法的基本设计思想。代码注释中

  2. 根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释

  3. 说明你所设计算法的时间复杂度和空间复杂度。

设计思想

如果存在那么一个数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)

你可能感兴趣的:(考研)