如何找到各种长度的连续序列的数量满足特定属性?

时间:2013-02-01 12:34:15

标签: c++ arrays algorithm

我得到一个数组A [],其中N个元素是正整数 。我必须找到满足特定属性的长度为1,2,3,...,N的序列数? 我已经构建了一个具有O(nlogn)复杂度的区间树。现在我想计算满足某个属性的序列数?

问题所需的所有属性都与序列的总和有关

注意,数组将具有N *(N + 1)/ 2个序列。如何在O(nlogn)或O(n)中迭代所有这些?

2 个答案:

答案 0 :(得分:0)

如果我们让k是从0到N(元素)的移动索引,我们将运行一个基本上寻找满足条件的MIN R的算法(比方说我),然后L = k的每个其他子集也满足于R> = I(这是你的短路)。找到I后,只需返回(L = k,R> = I)的输出。当然,这假设您集合中的所有数字都是> = 0。

要找到I,对于每个k,从元素k +(N-k)/ 2开始。确定这个定义的子集(L = k,R = k +(N-k)/ 2)是否满足您的条件。如果是这样,那么递减R直到你的条件不满足,那么R = 1就是你的MIN(你可以选择打印这些结果,但是它们导致这些情况基本上是向后打印的)。如果(L = k,R = k +(N-k)/ 2)不满足你的条件,那么INCREMENT R直到它为止,这就成了你L = k的MIN。这会使每个L = k的搜索空间降低2倍。当k增加并接近N时,搜索空间会不断减小。

// This declaration wont work unless N is either a constant or MACRO defined above
unsigned int myVals[N];
unsigned int Ndiv2 = N / 2;
unsigned int R;

for(unsigned int k; k < N; k++){

    if(TRUE == TESTVALS(myVals, k, Ndiv2)){ // It Passes
        for(I = NDiv2; I>=k; I--){
            if(FALSE == TESTVALS(myVals, k, I)){
                I++;
                break;
            } 
        }
    }else{                                  // It Didnt Pass
        for(I = NDiv2; I>=k; I++){
            if(TRUE == TESTVALS(myVals, k, I)){
                break;
            } 
        }
    }

    // PRINT ALL PAIRS from L=k, from R=I to R=N-1


    if((k & 0x00000001) == 0) Ndiv2++;

} // END --> for(unsigned int k; k < N; k++)

上述算法的复杂性为O(N ^ 2)。这是因为对于N中的每个k(即N次迭代/测试),每个需要测试的值都不大于N / 2。大O符号并不关心N / 2,也不是随着k增长真正N变小的事实,它实际上只关注总量。因此,它会说每N个值的N次测试,因此O(N ^ 2)

有一种替代方法可以更快。这种方法是每当你想在辅助(内部)for循环中移动时,你可以使用距离算法执行移动。这将使您进入O(nlogn)步骤集。对于N中的每个k(都必须进行测试),运行此半距离方法以logN时间查找MIN R值。举个例子,假设你有1000个元素数组。当k = 0时,我们基本上开始在索引500处搜索MIN R.如果测试通过,而不是从500向下线性移动到0,我们测试250.假设k = 0的实际MIN R是300.那么找到MIN R的测试结果如下:

R = 500 R = 250 R = 375 R = 312 R = 280 R = 296 R = 304 R = 300

虽然过于简单,但您最有可能需要进行优化,并测试301以及299,以确保您处于最佳位置。当你必须连续多次向同一方向移动时,除以2时要小心。

答案 1 :(得分:0)

@ user1907531:首先,如果你参加一个在国家层面具有如此重要性的在线竞赛,你应该避免采用这种便宜的技巧和方法来领先于其他应得的人。其次,像你这样的骗子总是骗子,但所有这些都妨碍了那些提出问题的人和不同于你的竞争者的辛勤工作。第三,如果@trumetlicks问你为什么没有把问题标记为作业,你又告诉另一个谎言。最后,我不知道怎么会有这么多人回答这个问题这个骗子问不知道原点/网站/这个问题的来源。老师在任何一所印度学校的家庭作业都无法做到这一点。告诉大家这个骗子在比赛结束前6小时已经问你在印度举办的大学比赛的完整解决方案,他肯定得到了很多直接的帮助,其中最受欢迎的是100名其他人在这里给出的答案作弊。所以,祝所有这些骗子好运。