简体   繁体   中英

Maximum sum in a contiguous subarray of a given 2D array

I have solved this problem but all the explanation given are with DP solutions having complexity at least N^3. I have solved it in N^2 I am wondering if my solution is wrong.

We are given a 2D array of integers (+ve and -ve), we are two find the subarray of this array having the maximum possible sum.

Algorithm that I have used is to fix 4 indices. For 2 columns I span from 0 to N to find where the maximum sum occurs and then I span from N to 0. From these two results I deduce from which column to which one will the sum be maximum. S Same approach I use for rows. Once, I get the 4 indices, I am done. Complexity: O(N^2)

Here is my code:

#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;
}

It's wrong. For instance, if the array is {{-1, -1, -1}, {-1, 1, -1},{-1, -1, -1}} , it prints 0 0 0 0 , while the correct answer's 1 1 1 1 (it's optimal to take the middle element as it's the only positive one).

Here is a correct O(n^3) solution: let's fix an upper row. Let's create an array of zeros. Now we'll iterate over rows from this one to the last one. We'll add each row to the array and call a 1-D solution for this array. After checking all upper rows, we just need to print the largest answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM