给定2D数组的连续子数组中的最大总和

时间:2016-12-09 17:12:59

标签: c++ arrays algorithm

我已经解决了这个问题但是给出的所有解释都是DP解决方案的复杂度至少为N ^ 3。我已经在N ^ 2中解决了它我想知道我的解决方案是否错误。

我们给出了一个整数的二维数组(+ ve和-ve),我们两个发现这个数组的子数组具有最大可能总和。

我使用的算法是修复4个索引。对于2列,我从0到N跨越以找到最大总和出现的位置,然后我从N到0跨越。从这两个结果中我推导出哪一列的总和最大。小号 我用于行的方法相同。有一次,我得到了4个指数,我完成了。 复杂性:O(N ^ 2)

这是我的代码:

#include <iostream>

using namespace std;

template<size_t n>
int find_col_sum(int A[][n], int m, int r1, int r2, int c) {
    int sum = 0;
    for (int i = r1; i <= r2; i++)
        sum += A[i][c];
    return sum;
}
template<size_t n>
int find_row_sum(int A[][n], int m, int c1, int c2, int r) {
    int sum = 0;
    for (int i = c1; i <= c2; i++)
        sum += A[r][i];
    return sum;
}

template<size_t n>
void max_sum_array(int A[][n], int m, int &i1, int &i2, int &i3, int &i4) {
    int mx1 = 0, mx2 = 0;
    int sum = 0, max1_sum = 0;
    int max2_sum = 0;

    //0 to col
    for (int i = 0; i < n; i++) {
        sum += find_col_sum(A,m,0,n-1,i);
        if (sum > max1_sum) {
            mx1 = i;
            max1_sum = sum;
        }
    }
    //n-1 to col
    sum = 0; mx2 = n-1;
    for (int i = n-1; i >= 0; i--) {
        sum += find_col_sum(A,m,0,n-1,i);
        if (sum > max2_sum) {
            mx2 = i;
            max2_sum = sum;
        }
    }
    if (mx1 <= mx2) {
        if (max1_sum >= max2_sum) {
            mx2 = mx1; mx1 = 0;
        }
        else {
            mx1 = mx2; mx2 = n-1;
        }
    }
    else
        swap(mx1,mx2);
    i1 = mx1; i2 = mx2;
    mx1 = 0; mx2 = m-1;
    max1_sum = 0; max2_sum = 0;
    sum = 0;
    //0 to row
    for (int i = 0; i < m; i++) {
        sum += find_row_sum(A,m,i1,i2,i);
        if (sum > max1_sum) {
            mx1 = i;
            max1_sum = sum;
        }
    }
    sum = 0;
    //m-1 to row
    for (int i = m-1; i >= 0; i--) {
        sum += find_row_sum(A,m,i1,i2,i);
        if (sum > max2_sum) {
            mx2 = i;
            max2_sum = sum;
        }
    }
    if (mx1 <= mx2) {
        if (max1_sum >= max2_sum) {
            mx2 = mx1; mx1 = 0;
        }
        else {
            mx1 = mx2; mx2 = m-1;
        }
    } else
        swap(mx1,mx2);
    i3 = mx1; i4 = mx2;
}

int main() {
    int A[][4] = {{0,-2,-7,0},{9,2,-6,2},{-4,1-4,1},{-1,8,0,-2}};
    int i1 = 0, i2 = 0, i3 = 0, i4 = 0;

    max_sum_array(A,4,i1,i2,i3,i4);
    cout<<i1<<" "<<i2<<" "<<i3<<" "<<i4<<endl;

    return 0;
}

1 个答案:

答案 0 :(得分:2)

这是错的。例如,如果数组为{{-1, -1, -1}, {-1, 1, -1},{-1, -1, -1}},则会打印0 0 0 0,而正确答案为1 1 1 1(因为它是中间元素的最佳选择) ; s是唯一积极的一个。)

这是一个正确的O(n ^ 3)解决方案: 让我们修一个上排。让我们创建一个零数组。现在我们将遍历从这一行到最后一行的行。我们将每行添加到数组中,并为此数组调用1-D解决方案。检查完所有上行后,我们只需要打印最大的答案。