Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions solution/0300-0399/0304.Range Sum Query 2D - Immutable/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,68 @@ public:
*/
```

### **Rust**

```rust
/**
* Your NumMatrix object will be instantiated and called as such:
* let obj = NumMatrix::new(matrix);
* let ret_1: i32 = obj.sum_region(row1, col1, row2, col2);
*/

struct NumMatrix {
// Of size (N + 1) * (M + 1)
prefix_vec: Vec<Vec<i32>>,
n: usize,
m: usize,
is_initialized: bool,
ref_vec: Vec<Vec<i32>>,
}


/**
* `&self` means the method takes an immutable reference.
* If you need a mutable reference, change it to `&mut self` instead.
*/
impl NumMatrix {

fn new(matrix: Vec<Vec<i32>>) -> Self {
NumMatrix {
prefix_vec: vec![vec![0; matrix[0].len() + 1]; matrix.len() + 1],
n: matrix.len(),
m: matrix[0].len(),
is_initialized: false,
ref_vec: matrix,
}
}

fn sum_region(&mut self, row1: i32, col1: i32, row2: i32, col2: i32) -> i32 {
if !self.is_initialized {
self.initialize_prefix_vec();
}
// Since i32 will let `rustc` complain, just make it happy
let row1: usize = row1 as usize;
let col1: usize = col1 as usize;
let row2: usize = row2 as usize;
let col2: usize = col2 as usize;
// Return the value in O(1)
self.prefix_vec[row2 + 1][col2 + 1] - self.prefix_vec[row2 + 1][col1]
- self.prefix_vec[row1][col2 + 1] + self.prefix_vec[row1][col1]
}

fn initialize_prefix_vec(&mut self) {
// Initialize the prefix sum vector
for i in 0..self.n {
for j in 0..self.m {
self.prefix_vec[i + 1][j + 1] =
self.prefix_vec[i][j + 1] + self.prefix_vec[i + 1][j] - self.prefix_vec[i][j] + self.ref_vec[i][j];
}
}
self.is_initialized = true;
}
}
```

### **Go**

```go
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,23 @@ numMatrix.sumRegion(1, 2, 2, 4); // return 12 (i.e sum of the blue rectangle)

## Solutions

Dynamic programming - 2D preSum.
We use $s[i + 1][j + 1]$ to represent the sum of all elements in the upper-left part up to the $i$-th row and $j$-th column, where the indices $i$ and $j$ both start from $0$.

We can derive the following prefix sum formula:

$$
s[i + 1][j + 1] = s[i + 1][j] + s[i][j + 1] - s[i][j] + nums[i][j]
$$

The sum of the elements in the rectangle with $(x_1, y_1)$ and $(x_2, y_2)$ as its upper-left and bottom-right corners respectively, is:

$$
s[x_2 + 1][y_2 + 1] - s[x_2 + 1][y_1] - s[x_1][y_2 + 1] + s[x_1][y_1]
$$

We preprocess the prefix sum array $s$ in the initialization method, and directly return the result of the above formula in the query method.

The time complexity for initialization is $O(m \times n)$, and the time complexity for query is $O(1)$.

<!-- tabs:start -->

Expand Down Expand Up @@ -140,6 +156,68 @@ public:
*/
```

### **Rust**

```rust
/**
* Your NumMatrix object will be instantiated and called as such:
* let obj = NumMatrix::new(matrix);
* let ret_1: i32 = obj.sum_region(row1, col1, row2, col2);
*/

struct NumMatrix {
// Of size (N + 1) * (M + 1)
prefix_vec: Vec<Vec<i32>>,
n: usize,
m: usize,
is_initialized: bool,
ref_vec: Vec<Vec<i32>>,
}


/**
* `&self` means the method takes an immutable reference.
* If you need a mutable reference, change it to `&mut self` instead.
*/
impl NumMatrix {

fn new(matrix: Vec<Vec<i32>>) -> Self {
NumMatrix {
prefix_vec: vec![vec![0; matrix[0].len() + 1]; matrix.len() + 1],
n: matrix.len(),
m: matrix[0].len(),
is_initialized: false,
ref_vec: matrix,
}
}

fn sum_region(&mut self, row1: i32, col1: i32, row2: i32, col2: i32) -> i32 {
if !self.is_initialized {
self.initialize_prefix_vec();
}
// Since i32 will let `rustc` complain, just make it happy
let row1: usize = row1 as usize;
let col1: usize = col1 as usize;
let row2: usize = row2 as usize;
let col2: usize = col2 as usize;
// Return the value in O(1)
self.prefix_vec[row2 + 1][col2 + 1] - self.prefix_vec[row2 + 1][col1]
- self.prefix_vec[row1][col2 + 1] + self.prefix_vec[row1][col1]
}

fn initialize_prefix_vec(&mut self) {
// Initialize the prefix sum vector
for i in 0..self.n {
for j in 0..self.m {
self.prefix_vec[i + 1][j + 1] =
self.prefix_vec[i][j + 1] + self.prefix_vec[i + 1][j] - self.prefix_vec[i][j] + self.ref_vec[i][j];
}
}
self.is_initialized = true;
}
}
```

### **Go**

```go
Expand Down
57 changes: 57 additions & 0 deletions solution/0300-0399/0304.Range Sum Query 2D - Immutable/Solution.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* Your NumMatrix object will be instantiated and called as such:
* let obj = NumMatrix::new(matrix);
* let ret_1: i32 = obj.sum_region(row1, col1, row2, col2);
*/

struct NumMatrix {
// Of size (N + 1) * (M + 1)
prefix_vec: Vec<Vec<i32>>,
n: usize,
m: usize,
is_initialized: bool,
ref_vec: Vec<Vec<i32>>,
}


/**
* `&self` means the method takes an immutable reference.
* If you need a mutable reference, change it to `&mut self` instead.
*/
impl NumMatrix {

fn new(matrix: Vec<Vec<i32>>) -> Self {
NumMatrix {
prefix_vec: vec![vec![0; matrix[0].len() + 1]; matrix.len() + 1],
n: matrix.len(),
m: matrix[0].len(),
is_initialized: false,
ref_vec: matrix,
}
}

fn sum_region(&mut self, row1: i32, col1: i32, row2: i32, col2: i32) -> i32 {
if !self.is_initialized {
self.initialize_prefix_vec();
}
// Since i32 will let `rustc` complain, just make it happy
let row1: usize = row1 as usize;
let col1: usize = col1 as usize;
let row2: usize = row2 as usize;
let col2: usize = col2 as usize;
// Return the value in O(1)
self.prefix_vec[row2 + 1][col2 + 1] - self.prefix_vec[row2 + 1][col1]
- self.prefix_vec[row1][col2 + 1] + self.prefix_vec[row1][col1]
}

fn initialize_prefix_vec(&mut self) {
// Initialize the prefix sum vector
for i in 0..self.n {
for j in 0..self.m {
self.prefix_vec[i + 1][j + 1] =
self.prefix_vec[i][j + 1] + self.prefix_vec[i + 1][j] - self.prefix_vec[i][j] + self.ref_vec[i][j];
}
}
self.is_initialized = true;
}
}