Monday, May 17, 2021

 Problem statement: Find the maximal sum of elements in a rectangular region of an integer matrix 

Solution:  

    public static int getMax(int[][] A) {

        assert (A != null && A.length > 0 && A[0].length > 0);

        int result = 0; // maximum profit of a rectangle

        int M = A.length;

        int N = A[0].length;

        if (M > N) {

            // transpose

            int[][] A1 = new int[N][M];

            for (int j = 0; j < N; j++) {

                for (int i = 0; i < M; i++) {

                    A1[j][i] = A[i][j];

                }

            }

            A = A1;

            M = A1.length;

            N = A1[0].length;

        }

        int[][] sum = new int[M+1][N+1];

        for (int i = 1; i < M + 1; i++) {

            for (int j = 1; j < N + 1; j++) {

                sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + A[i-1][j-1];

            }

        } 

        for (int i1 = 0; i1 < M; i1++) {

            for (int i2 = i1+1; i2 < M+1; i2++) {

                // region init

                int min1 = 0; // minimum value of a rectangle [i1..i2-1]x[0..j-1]

                int minJ1 = 0; // minimum for such j when minimum in one dimension using a formula like that for sum but in one dimension

                // sum'[j] = sum[i2 + 1][j] - sum[i1][j]

                int maxValue1 = 0; // maximum value of a rectangle [i1..i2-1]x[j'..j-1]

                int max1 = 0; // maximum value of a rectangle [i1..i2-1]x[0..j-1]

                int maxJ1 = 0; // minimum such j

 

                int minCost1 = 0; // minimum value of a rectangle [i1..i2-1]x[j'..j-1]

                int min2 = 0; // minimum value of a rectangle [0..i1-1, i2..M-1] x [0..j-1]

                int minJ2 = 0; // maximum such j

 

                int maxValue2 = 0; // maximum value of a rectangle [0..i1-1, i2..M-1] x [j'..j-1]

                int max2 = 0; // maximum value of a rectangle [0..i1-1, i2..M-1] x [0..j-1]

                int maxJ2 = 0; // minimum such j

 

                int minCost2 = 0; // minimum value of a rectangle [0..i1-1, i2..M-1] x [j'..j-1]

                // endregion init

                for (int j = 1; j < N+1; j++) {

                    int value1 = sum[i2][j] - sum[i1][j];

                    min1 = Math.min(value1, min1);

                    minJ1 = (value1 == min1)? j : minJ1;

                    maxValue1 = Math.max(value1 - min1, maxValue1);

                    max1 = Math.max(max1, value1);

                    maxJ1 = (max1 == value1) ? j : maxJ1;

                    minCost1 = Math.min(minCost1, value1 - max1);

                    int value2 = sum[M][j] - value1;

                    min2 = Math.min(min2, value2);

                    minJ2 = (min2 == value2) ? j : minJ2;

                    maxValue2 = Math.max(maxValue2, value2 - min2);

                    max2 = Math.max(value2, max2);

                    maxJ2 = (max2 == value2)  ? j : maxJ2;

                    minCost2 = Math.min(minCost2, value2 - max2);

                    result = Arrays.asList(result, maxValue1, maxValue2, value1 - minCost1, value2 - minCost2).stream().mapToInt(x -> x).max().getAsInt();

                }

            }

        }

        return result;

    }


    public static void main(String[] args) { 

        int[][] A = new int[2][2]; 

        A[0][0] = 1; 

        A[0][1] = 1; 

        A[1][0] = 1; 

        A[1][1] = 0; 

        System.out.println(getMax(A)); 

3 // output


No comments:

Post a Comment