Given a 2D matrixmatrix, find the sum of the elements inside the rectangle defined by its upper left corner (row1,col1) and lower right corner (row2,col2).
The above rectangle (with the red border) is defined by (row1, col1) =(2, 1)and (row2, col2) =(4, 3), which contains sum =8.
Complexity: Linear to the number of elements n, in both time and space.
The Idea: We begin by building what is a called an integral matrix. An integral matrix uses the same principles as an integral array , but just expanded to 2 dimensions. An integral array is just the accumulative summation of elements within the array. For example:
Using this array, the idea is that now we can represent any cumulative subset of the array in O(1) time. Intuitively, this mean taking every accumulated to the end point, and subtracting it with the access we don't care about.
Using the same principles, we can generalize this to 2 dimensions.
Then a summation would look like this. Notice we are subtracting the upper corner twice, so we have to add it back in, just in set theory where (A or B) = A + B - (A and B)
classNumMatrix {public:NumMatrix(vector<vector<int>> matrix):matrix(matrix) {if (!matrix.empty()) { rowSize =matrix.size(); colSize =matrix.at(0).size();integralMatrix.resize(rowSize);for (auto&i : integralMatrix) i.resize(colSize);computeIntegralMatrix(); } }intsumRegion(int row1,int col1,int row2,int col2) {if (matrix.empty()) return0;int bottom_right =integralMatrix[row2][col2];int bottom_left =isValid(row2, col1 -1) ?integralMatrix[row2][col1 -1] :0;int top_right =isValid(row1 -1, col2) ?integralMatrix[row1 -1][col2] :0;int diagonal =isValid(row1 -1, col1 -1) ?integralMatrix[row1 -1][col1 -1] :0;return bottom_right - bottom_left - top_right + diagonal; cout <<' '; }private:size_t rowSize, colSize;voidcomputeIntegralMatrix() {for (int i =0; i < rowSize; i++) {for (int j =0; j < colSize; j++) {int top =isValid(i -1, j) ?integralMatrix[i -1][j] :0;int left =isValid(i, j -1) ?integralMatrix[i][j -1] :0;int diagonal =isValid(i -1, j -1) ?integralMatrix[i -1][j -1] :0;integralMatrix[i][j] = top + left - diagonal +matrix[i][j]; } } }boolisValid(constint&row,constint&col) {return (row >=0&& col >=0&& row < rowSize && col < colSize); } vector<vector<int>> matrix; vector<vector<int>> integralMatrix;};/*** Your NumMatrix object will be instantiated and called as such:* NumMatrix obj = new NumMatrix(matrix);* int param_1 = obj.sumRegion(row1,col1,row2,col2);*/