查找最大数量为1s的2D数组的连续行

abcdf ndjdnkn

我有2D大小的数组,m*m元素值为0s或1s。此外,数组的每一列都有一个连续的1s块(该块之外为0)。数组本身太大,无法保存在内存中(最多10 ^ 6行),但是对于每一列,我都可以确定该列中1的下限a和上限b对于给定n,我需要找出n最大数量为1的那些连续行。对于一个较小的数字,我可以轻松地做到这一点,方法是逐行计算每一行的总和,然后选择n总和最大的连续行,但是对于较大的数字,这会浪费太多时间。有什么有效的方法可以计算出来吗?也许使用动态编程?

这是一个示例代码片段,显示了我当前的方法,其中对的连续调用read_int()(此处未给出)提供了连续列的上下限:

   long int harr[10000]={0};       //initialized to zero
   for(int i=0;i<m;i++)
    {
        a=read_int();
        b=read_int();
        for(int j=a;j<=b;j++)        // for finding sum of each row
           harr[j]++;
    }
   answer=0;
    for(int i=0;i<n;i++)
    {
        answer=answer+harr[i];
    }
    current=answer;
    for(int i=n;i<m;i++)
    {
        current=current+harr[i]-harr[i-n];
        if(current>answer)
        {
            answer=current;
        }
    }

例如(具有m= 6和n= 3)

在此处输入图片说明

答案是第1到第3行,这些行中的1总数为13。(如果有平局,则第2行到第4行也会使总和最大化。)

约翰·科尔曼

这是另一种方法。认为每对ab作为定义形式[A,B + 1)的间隔。任务是找到n使该区间中数字括号深度之和最大连续索引每一个新的a颠簸在括号深度a可达1。每一个新的b原因括号深度后, b由1下井在第一次-只要加载这些括号深度增量。然后,一遍从这些增量中获得括号深度。以下代码说明了这种方法。m为了测试目的,我减少到了6个,并read_int()通过访问硬连线数组(对应于问题中的示例)替换了对未知对象调用

#include <stdio.h>

int main(void){
    int a,b,answer,current,lower,upper;
    int n = 3;
    int lower_bound[6] = {0,1,2,3,1,2};
    int upper_bound[6] = {3,4,3,5,2,4};
    int m = 6;
    int harr[6]={0};

    //load parenthesis depth-deltas (all initially 0)
       for(int i=0;i<m;i++)
        {
            a = lower_bound[i];
            b = upper_bound[i];
            harr[a]++;
            if(b < m-1)harr[b+1]--;
        }

    //determine p-depth at each point
        for(int i = 1; i < m; i++){
            harr[i] += harr[i-1];
        }

    //find optimal n-rows by sliding-window
       answer = 0;
        for(int i=0;i<n;i++)
        {
            answer = answer+harr[i];
        }
        current  =answer;
        lower = 0;
        upper = n-1;

        for(int i=n;i<m;i++)
        {
            current = current+harr[i]-harr[i-n];
            if(current>answer)
            {
                answer = current;
                lower = i-n+1;
                upper = i;
            }
        }
    printf("Max %d rows are %d to %d with a total sum of %d ones\n", n,lower,upper,answer);
    return 0;
}

(显然,harr可以将加载的循环与计算的循环合并answer。我将其保留为两次,以更好地说明如何harr从括号delta中获取最终的逻辑)。

编译并运行此代码时,其输出为:

Max 3 rows are 1 to 3 with a total sum of 13 ones

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章