Increment Submatrices by One


Problem

You are given a positive integer nn, indicating that we initially have an n×nn \times n 0-indexed integer matrix matmat filled with zeroes.

You are also given a 2D integer array queryquery. For each queryi=[row1i,col1i,row2i,col2i]query_i = [row1_i, col1_i, row2_i, col2_i], you should do the following operation:

  • Add 11 to every element in the submatrix with the top left corner (row1i,col1i)(row1_i, col1_i) and the bottom right corner (row2i,col2i)(row2_i, col2_i).
  • That is, add 11 to mat[x][y]mat[x][y] for for all row1ixrow2irow1_i \leq x \leq row2_i and col1iycol2icol1_i \leq y \leq col2_i.

Return the matrix matmat after performing every query.

Example

example 1

Input: n = 3, queries = [[1,1,2,2],[0,0,1,1]]
Output: [[1,1,0],[1,2,1],[0,1,1]]
Explanation: The diagram above shows the initial matrix, the matrix after the first query, and the matrix after the second query.
- In the first query, we add 1 to every element in the submatrix with the top left corner (1, 1) and bottom right corner (2, 2).
- In the second query, we add 1 to every element in the submatrix with the top left corner (0, 0) and bottom right corner (1, 1).

example 2

Input: n = 2, queries = [[0,0,1,1]]
Output: [[1,1],[1,1]]
Explanation: The diagram above shows the initial matrix and the matrix after the first query.
- In the first query we add 1 to every element in the matrix.

Constraints

  • 1n5001 \leq n \leq 500
  • 1queries.length1041 \leq queries.length \leq 104
  • 0row1irow2i<n0 \leq row1_i \leq row2_i < n
  • 0col1icol2i<n0 \leq col1_i \leq col2_i < n

Submit your solution at here

Solution

Brute Force (TLE)

The brute force approach has O(m×n2)O(m \times n^2) complexity and very likely to TLE. But I heard some people managed to AC with it. I was not that lucky and got TLE.

class Solution {
public:
    vector<vector<int>> rangeAddQueries(int n, vector<vector<int>>& queries) {
        vector<vector<int>> ret(n, vector<int>(n, 0));
        for(auto& q: queries) {
            for(int i = q[0];i<=q[2];i++)
                for(int j = q[1];j<=q[3];j++)
                    ret[i][j]++;
        }
        return ret;
    }
};

Intuition

We will solve this row by row. On each row, we manage an array deltadelta to keep track of how the value change. Let deltai=kdelta_i = k denotes that ansi=ansi1+kans_i = ans_{i-1}+k For each query qq that span from [a,b][a,b] it will make deltaa=deltaa+1delta_a = delta_a + 1 and deltab+1=deltab+11delta_{b+1} = delta_{b+1} - 1, everything in the middle would not change and stay as is. We can build the deltadelta array in O(m×n)O(m \times n) where mm is the queries.lengthqueries.length. We also need a nested loop to update the array so the overall complexity would be O(m×n+n2)O(m \times n+n^2)

Complexity

  • Time complexity: O(m×n+n2)O(m \times n+n^2)
  • Space complexity: O(n2)O(n^2)

Code

class Solution {
public:
    vector<vector<int>> rangeAddQueries(int n, vector<vector<int>>& queries) {
        vector<vector<int>> ret(n, vector<int>(n, 0));
        vector<vector<int>> delta(n, vector<int>(n, 0));
        for(auto& q: queries) {
            int x0 = q[0], y0 = q[1], xn = q[2], yn = q[3];
            for(int y = y0;y<=yn;y++) {
                delta[x0][y]++;
                if(xn+1 >= n) continue;
                delta[xn+1][y]--;
            }
        }
        for(int x = 0;x<n;x++) {
            for(int y = 0;y<n;y++) {
                auto prev = (x == 0?0:ret[x-1][y]);
                ret[x][y] = prev + delta[x][y];
            }
        }
        return ret;
    }
};

FYI

I failed today’s contest 😭😭😭 There goes my rating.

TLE failed