> For the complete documentation index, see [llms.txt](https://maksimdan.gitbook.io/interview-practice-problems/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://maksimdan.gitbook.io/interview-practice-problems/leetcode_sessions/304-range-sum-query-2d-immutable.md).

# 304 Range Sum Query 2D - Immutable

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).

![Range Sum Query 2D](https://leetcode.com/static/images/courses/range_sum_query_2d.png)\
The above rectangle (with the red border) is defined by (row1, col1) =**(2, 1)**&#x61;nd (row2, col2) =**(4, 3)**, which contains sum =**8**.

**Example:**

```
Given matrix = [
  [3, 0, 1, 4, 2],
  [5, 6, 3, 2, 1],
  [1, 2, 0, 1, 5],
  [4, 1, 0, 1, 7],
  [1, 0, 3, 0, 5]
]

sumRegion(2, 1, 4, 3) -
>
 8
sumRegion(1, 1, 2, 2) -
>
 11
sumRegion(1, 2, 2, 4) -
>
 12
```

**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:

![](/files/-LoJIcfTXGcAQ0zsyR3P)

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.

![](/files/-LoJIcfViv8eJIXlqjA7)

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)

![](/files/-LoJIcfXOcbbkpWjM9ae)

```cpp
class NumMatrix {
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();
        }
    }

    int sumRegion(int row1, int col1, int row2, int col2)
    {
        if (matrix.empty()) return 0;

        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;

    void computeIntegralMatrix()
    {
        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];
            }
        }
    }

    bool isValid(const int &row, const int &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);
*/
```

**Some Testing:**

```
int main()
{
    vector<vector<int>> matrix1 = {
        {1,2,3},
        {4,5,6},
        {7,8,9}
    };
    NumMatrix obj = NumMatrix(matrix1);
    assert(obj.sumRegion(1, 1, 2, 2) == 28);
    assert(obj.sumRegion(0, 0, 1, 1) == 12);
    assert(obj.sumRegion(0, 0, 0, 0) == 1);
    assert(obj.sumRegion(0, 1, 0, 1) == 2);

    vector<vector<int>> matrix2 = { { -5208,1041,-93779,-64152,17850,29055,-63731,-23568,41170,58457,-39616,55683,-51662,-75015,21726 },{ 4535,-72412,86878,-60825,67088,48794,-23471,-22403,58200,-31153,-94668,-27274,-11003,33894,-66125 },{ -9538,-33861,54822,42636,48430,-56030,-33348,-30617,5219,56501,-95879,-73537,-18157,-72815,-40977 },{ 15602,40115,-32475,99011,47251,84035,83793,-74389,-99042,65460,11671,-95294,68311,47893,71866 },{ 69607,57288,55022,36610,-75113,31344,34319,-13381,-74800,-71904,-15625,-5398,-29689,-68805,-41994 },{ -32276,95017,-96452,-47311,13238,46324,95358,13247,-30930,5815,-36748,-25712,-83982,29391,-73922 },{ -29140,-70403,-3168,12219,-4473,-10013,-85502,87222,-44858,66506,-99821,-16992,-80758,59210,87145 },{ -9557,67725,-27359,-28647,46781,-67948,-28154,-3498,91489,-3887,-96422,6568,42380,73264,-55406 },{ 40555,70153,-51490,-14237,9684,-54000,-8443,-32063,-96157,-70083,-7050,56221,93013,-1157,-45593 },{ -28686,-54296,628,11189,18227,-64455,-10528,-69244,94796,-39806,69194,45024,-14417,-51291,6387 },{ -28485,36898,97259,-83875,83650,-36715,80692,-55055,40025,-69379,-1548,-13045,23318,79349,-42774 },{ 82645,17721,84052,-35036,-751,90269,-77187,51972,-90217,-5956,-34552,95560,40436,51650,72778 },{ -970,77788,10423,-1406,-90844,6732,-60197,59393,-82111,33737,-4731,-52679,-12011,69741,-91931 } };
    NumMatrix obj2 = NumMatrix(matrix2);

    cout << obj2.sumRegion(3, 2, 12, 6) << endl;
    cout << obj2.sumRegion(11, 10, 11, 12) << endl;
    cout << obj2.sumRegion(7, 7, 7, 10) << endl;
    cout << obj2.sumRegion(7, 10, 10, 13) << endl;
    cout << obj2.sumRegion(2, 11, 5, 12) << endl;
    cout << obj2.sumRegion(10, 8, 10, 12) << endl;
    cout << obj2.sumRegion(12, 7, 12, 10) << endl;
    cout << obj2.sumRegion(1, 14, 9, 14) << endl;
    cout << obj2.sumRegion(11, 11, 11, 13) << endl;
    cout << obj2.sumRegion(7, 7, 9, 10) << endl;
    cout << obj2.sumRegion(12, 8, 12, 12) << endl;
    cout << obj2.sumRegion(1, 4, 6, 11) << endl;
    cout << obj2.sumRegion(0, 9, 9, 13) << endl;
    cout << obj2.sumRegion(9, 6, 9, 13) << endl;
    cout << obj2.sumRegion(10, 14, 11, 14) << endl;
    cout << obj2.sumRegion(4, 9, 7, 14) << endl;
    cout << obj2.sumRegion(5, 13, 7, 14) << endl;
    cout << obj2.sumRegion(12, 0, 12, 14) << endl;
    cout << obj2.sumRegion(9, 14, 11, 14) << endl;
    cout << obj2.sumRegion(2, 8, 10, 13) << endl;
    cout << obj2.sumRegion(3, 5, 12, 8) << endl;
    cout << obj2.sumRegion(5, 3, 11, 10) << endl;
    cout << obj2.sumRegion(1, 14, 11, 14) << endl;
    cout << obj2.sumRegion(8, 2, 11, 6) << endl;
    cout << obj2.sumRegion(3, 13, 12, 14) << endl;
    cout << obj2.sumRegion(4, 9, 11, 12) << endl;
    cout << obj2.sumRegion(7, 1, 9, 2) << endl;
    cout << obj2.sumRegion(0, 0, 8, 14) << endl;
    cout << obj2.sumRegion(11, 8, 12, 10) << endl;
    cout << obj2.sumRegion(1, 1, 10, 13) << endl;
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://maksimdan.gitbook.io/interview-practice-problems/leetcode_sessions/304-range-sum-query-2d-immutable.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
