-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrange-sum-query-2d-immutable.js
More file actions
124 lines (111 loc) · 3.47 KB
/
Copy pathrange-sum-query-2d-immutable.js
File metadata and controls
124 lines (111 loc) · 3.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// https://leetcode.com/problems/range-sum-query-2d-immutable/
// Related Topics: Dynamic Programming
// Difficulty: Medium
/*
Initial thoughts:
The naive approach is to look at each and every element every time
and sum them. This would have a Time Complexity of O(n) and a Space Complexity of O(1)
Optimization:
Using a Dynamic Programming approach, we can create a suplemental matrix where each element
contains the sum of all the values before it in that specific row plus itself.
Now to find the sum of the elements in a box in the matrix we need to add the sums for each
row in that box.
This is very similar to range-sum-query-immutable.py and its solution and will only add another
dimension to the whole problem.
Preprocessing will take up O(n) where n === matrix.width * matrix.heigth
Lookup time for a box inside the matrix is O(matrix.height) since the sum of a row can be calculated
in constant time.
Time complexity: O(n) where n === matrix.width * matrix.heigth
Space complexity: O(n) where n === matrix.width * matrix.heigth
*/
/**
* @param {number[][]} matrix
*/
var NumMatrix = function(matrix) {
this.matrix = matrix;
this.dp = this.preprocess();
};
/**
* @param {number} row1
* @param {number} col1
* @param {number} row2
* @param {number} col2
* @return {number}
*/
NumMatrix.prototype.sumRegion = function(row1, col1, row2, col2) {
let sum = 0;
for (let i = row1; i <= row2; i++) {
sum += this.dp[i][col2 + 1] - this.dp[i][col1];
}
return sum;
};
NumMatrix.prototype.preprocess = function() {
const dp = [];
for (let i = 0; i < this.matrix.length; i++) {
const row = Array(this.matrix[0].length + 1).fill(0);
for (let j = 0; j < this.matrix[0].length; j++) {
row[j + 1] = row[j] + this.matrix[i][j];
}
dp.push(row);
}
return dp;
};
/**
* @param {number} row1
* @param {number} col1
* @param {number} row2
* @param {number} col2
* @return {number}
*/
NumMatrix.prototype.sumRegionNaive = function(row1, col1, row2, col2) {
let sum = 0;
for (let i = row1; i <= row2; i++)
for (let j = col1; j <= col2; j++) sum += this.matrix[i][j];
return sum;
};
/*
Optimization:
We could render the lookup time constant by storing the sum of the whole box before an element
in the dp array. Then with some basic arithmetic we can calculate any box in the matrix.
Time Complexity: O(n) where n === matrix.width * matrix.heigth
Space Complexity: O(n) where n === matrix.width * matrix.heigth
*/
/**
* @param {number[][]} matrix
*/
var NumMatrix = function(matrix) {
this.matrix = matrix;
this.dp = this.preprocess();
};
/**
* @param {number} row1
* @param {number} col1
* @param {number} row2
* @param {number} col2
* @return {number}
*/
NumMatrix.prototype.sumRegion = function(row1, col1, row2, col2) {
return (
this.dp[row2 + 1][col2 + 1] -
this.dp[row1][col2 + 1] -
this.dp[row2 + 1][col1] +
this.dp[row1][col1]
);
};
NumMatrix.prototype.preprocess = function() {
if (this.matrix.length === 0 || this.matrix[0].length === 0) return null;
const dp = [Array(this.matrix[0].length + 1).fill(0)];
for (let i = 0; i < this.matrix.length; i++) {
const row = Array(this.matrix[0].length + 1).fill(0);
for (let j = 0; j < this.matrix[0].length; j++) {
row[j + 1] = dp[i][j + 1] + row[j] - dp[i][j] + this.matrix[i][j];
}
dp.push(row);
}
return dp;
};
/**
* Your NumMatrix object will be instantiated and called as such:
* var obj = new NumMatrix(matrix)
* var param_1 = obj.sumRegion(row1,col1,row2,col2)
*/