查询大小为K的所有连续子阵列

时间:2017-08-06 06:50:06

标签: c++ algorithm data-structures

让我们在大小为B[1:K]的数组K上定义一个操作,即计算子数组B[2:K]中小于B[1]的元素数。

现在我有一个大小为A[1:N]的数组N,我的目标是对所有大小为K的连续子数组执行上述操作。

实施例

A = [4, 3, 6, 2, 1] and K = 3 3大小为3个连续的子阵列。

  1. B = [4, 3, 6] count = 1 [(3 < 4)]
  2. B = [3, 6, 2] count = 1 [(2 < 3)]
  3. B = [6, 2, 1] count = 2 [(2 < 6), (1 < 6)]
  4. 蛮力方法的时间复杂度为O((N-K+1)*K),因为对大小为K的连续子阵列执行上述操作为O(K)

    如果可以设计数据结构,我可以在Nlog(M)中高效地完成 它具有以下属性

    1. log(M)
    2. 中插入
    3. log(M)
    4. 中的删除
    5. X
    6. 中计算小于log(M)的元素数量

      我是C++用户,我不认为有任何数据结构可以满足所有上述要求。还有其他改进方法吗?请帮忙。

2 个答案:

答案 0 :(得分:1)

您可能希望使用set来计算小于k的元素的附加操作。这可以实现为二进制搜索树(经典集合实现),在每个节点中具有附加统计(基本上是树中节点的大小)。

此处有更多详情:https://stackoverflow.com/a/15321444/1391392 这里有一些实现:https://sourceforge.net/projects/orderstatistics/

其他选项可能看起来更直接,就是使用跳过列表。 https://en.wikipedia.org/wiki/Skip_list

答案 1 :(得分:0)

这有帮助吗?

#include <iostream>
#include <cstdio>
#include <set>
using namespace std;
int bit[100005]={0};
// using BIT since numbers can repeat and set won't work
void update(int idx, int val, int n){
    while(idx < n){
        bit[idx] += val;
        idx += (idx & -idx);
    }
}
int get(int idx){
    int ret = 0;
    while(idx > 0){
        ret += bit[idx];
        idx -= (idx & -idx);
    }
    return ret;
}
int main() {
    int n, a[100005] = {0}, i, ans=0, k, maxx = -1;
    scanf("%d%d", &n, &k);
    for(i=0; i<n; i++){
        scanf("%d", &a[i]);
        if(maxx < a[i]){
            maxx = a[i];
        }
    }
    maxx++;
    for(i=0;i<n;i++){
        a[i] = maxx - a[i];
    }

    // now the problem becomes the opposite of what it initially was
    // now a[i] would contribute to ans if we can find an element a[j] where a[j] < a[i] and (i-j)<=k

    for(i=0;i<n;i++){
        if(i-k>=0){
            // remove i-k'th element from the BIT since it doesn't contribute
            update(a[i-k], -1, maxx);   
        }
        if(i >= k-1){
            // add how a[i] is gonna contribute to the final answer, it would be the number of elements less than a[i]
            ans += get(a[i]);
        }
        // add a[i] to the BIT
        update(a[i], 1, maxx);
    }
    printf("%d\n", ans);
    return 0;
}