Range Sum Query 2D - Immutable in C++
Suppose we have a 2D matrix called matrix, we have to find the sum of the elements inside the rectangle defined by its upper left corner using (row1, col1) and lower right corner using (row2, col2).
So if the matrix is like −
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 |
The above rectangle with the blue color defined by (2,1) and (4,3), this contains sum 8.
So if we perform some query like sumRegion(2, 1, 4, 3), sumRegion(1, 1, 2, 2), sumRegion(1, 2, 2, 4), these will return 8, 11, 12 respectively.
To solve this, we will follow these steps −
Define a matrix called dp.
Initialize the task as follows
n := number of rows. if n is 0, then return,
m := number of columns
dp := another matrix of size n x m
for i in range 0 to n
for j in range 0 to m
when j – 1 < 0, then set dp[i, j] as matrix[i, j], otherwise set this as (dp[i, j - 1] + matrix[i, j])
for i in range 1 to n
for j in range 0 to m
increase dp[i, j] by dp[i – 1, j]
For the query method, this will take row1, col1, row2, col2
ret := dp[row2, col2]
sub1 := 0 when row1 – 1 < 0, otherwise it will be dp[row1 – 1, col2]
sub2 := 0 when col1 – 1 < 0, otherwise it will be dp[row2, col1 - 1]
if row1 – 1 < 0 or col1 – 1 < 0, then
add := 0
otherwise add := dp[row1 – 1, col1 – 1]
return ret – sub1 – sub2 + add
Example(C++)
Let us see the following implementation to get better understanding −
#include <bits/stdc++.h> using namespace std; class NumMatrix { public: vector < vector <int>> dp; NumMatrix(vector<vector<int>>& matrix) { int n = matrix.size(); if(!n) return; int m = matrix[0].size(); dp = vector < vector <int>>(n, vector <int> (m)); for(int i = 0; i < n; i++){ for(int j = 0 ;j < m; j++){ dp[i][j] = j - 1 < 0 ? matrix[i][j] : dp[i][j - 1] + matrix[i][j]; } } for(int i = 1; i < n; i++){ for(int j = 0; j < m; j++){ dp[i][j] += dp[i - 1][j]; } } } int sumRegion(int row1, int col1, int row2, int col2) { int ret = dp[row2][col2]; int sub1 = row1 - 1 < 0 ? 0 : dp[row1 - 1][col2]; int sub2 = col1 - 1 < 0 ? 0 : dp[row2][col1 - 1]; int add = row1 - 1 < 0 || col1 - 1 < 0 ? 0 : dp[row1 - 1][col1 - 1]; return ret - sub1 - sub2 + add; } }; main(){ vector<vector<int>> mat = {{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}}; NumMatrix ob(mat); cout << ob.sumRegion(2,1,4,3) << endl; cout << ob.sumRegion(1,1,2,2) << endl; cout << ob.sumRegion(1,2,2,4) << endl; }
Input
[[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) sumRegion(1,1,2,2) sumRegion(1,2,2,4)
Output
8 11 12