Welcome to Subscribe On Youtube
3242. Design Neighbor Sum Service
Description
You are given a n x n
2D array grid
containing distinct elements in the range [0, n2 - 1]
.
Implement the NeighborSum
class:
NeighborSum(int [][]grid)
initializes the object.int adjacentSum(int value)
returns the sum of elements which are adjacent neighbors ofvalue
, that is either to the top, left, right, or bottom ofvalue
ingrid
.int diagonalSum(int value)
returns the sum of elements which are diagonal neighbors ofvalue
, that is either to the top-left, top-right, bottom-left, or bottom-right ofvalue
ingrid
.
Example 1:
Input:
["NeighborSum", "adjacentSum", "adjacentSum", "diagonalSum", "diagonalSum"]
[[[[0, 1, 2], [3, 4, 5], [6, 7, 8]]], [1], [4], [4], [8]]
Output: [null, 6, 16, 16, 4]
Explanation:
- The adjacent neighbors of 1 are 0, 2, and 4.
- The adjacent neighbors of 4 are 1, 3, 5, and 7.
- The diagonal neighbors of 4 are 0, 2, 6, and 8.
- The diagonal neighbor of 8 is 4.
Example 2:
Input:
["NeighborSum", "adjacentSum", "diagonalSum"]
[[[[1, 2, 0, 3], [4, 7, 15, 6], [8, 9, 10, 11], [12, 13, 14, 5]]], [15], [9]]
Output: [null, 23, 45]
Explanation:
- The adjacent neighbors of 15 are 0, 10, 7, and 6.
- The diagonal neighbors of 9 are 4, 12, 14, and 15.
Constraints:
3 <= n == grid.length == grid[0].length <= 10
0 <= grid[i][j] <= n2 - 1
- All
grid[i][j]
are distinct. value
inadjacentSum
anddiagonalSum
will be in the range[0, n2 - 1]
.- At most
2 * n2
calls will be made toadjacentSum
anddiagonalSum
.
Solutions
Solution 1: Hash Table
We can use a hash table $\textit{d}$ to store the coordinates of each element. Then, according to the problem description, we separately calculate the sum of adjacent elements and diagonally adjacent elements.
In terms of time complexity, initializing the hash table has a time complexity of $O(m \times n)$, and calculating the sum of adjacent elements and diagonally adjacent elements has a time complexity of $O(1)$. The space complexity is $O(m \times n)$.
-
class neighborSum { private int[][] grid; private final Map<Integer, int[]> d = new HashMap<>(); private final int[][] dirs = { {-1, 0, 1, 0, -1}, {-1, 1, 1, -1, -1} }; public neighborSum(int[][] grid) { this.grid = grid; int m = grid.length, n = grid[0].length; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { d.put(grid[i][j], new int[] {i, j}); } } } public int adjacentSum(int value) { return cal(value, 0); } public int diagonalSum(int value) { return cal(value, 1); } private int cal(int value, int k) { int[] p = d.get(value); int s = 0; for (int q = 0; q < 4; ++q) { int x = p[0] + dirs[k][q], y = p[1] + dirs[k][q + 1]; if (x >= 0 && x < grid.length && y >= 0 && y < grid[0].length) { s += grid[x][y]; } } return s; } } /** * Your neighborSum object will be instantiated and called as such: * neighborSum obj = new neighborSum(grid); * int param_1 = obj.adjacentSum(value); * int param_2 = obj.diagonalSum(value); */
-
class neighborSum { public: neighborSum(vector<vector<int>>& grid) { this->grid = grid; int m = grid.size(), n = grid[0].size(); for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { d[grid[i][j]] = {i, j}; } } } int adjacentSum(int value) { return cal(value, 0); } int diagonalSum(int value) { return cal(value, 1); } private: vector<vector<int>> grid; unordered_map<int, pair<int, int>> d; int dirs[2][5] = { {-1, 0, 1, 0, -1}, {-1, 1, 1, -1, -1} }; int cal(int value, int k) { auto [i, j] = d[value]; int s = 0; for (int q = 0; q < 4; ++q) { int x = i + dirs[k][q], y = j + dirs[k][q + 1]; if (x >= 0 && x < grid.size() && y >= 0 && y < grid[0].size()) { s += grid[x][y]; } } return s; } }; /** * Your neighborSum object will be instantiated and called as such: * neighborSum* obj = new neighborSum(grid); * int param_1 = obj->adjacentSum(value); * int param_2 = obj->diagonalSum(value); */
-
class neighborSum: def __init__(self, grid: List[List[int]]): self.grid = grid self.d = {} self.dirs = ((-1, 0, 1, 0, -1), (-1, 1, 1, -1, -1)) for i, row in enumerate(grid): for j, x in enumerate(row): self.d[x] = (i, j) def adjacentSum(self, value: int) -> int: return self.cal(value, 0) def cal(self, value: int, k: int): i, j = self.d[value] s = 0 for a, b in pairwise(self.dirs[k]): x, y = i + a, j + b if 0 <= x < len(self.grid) and 0 <= y < len(self.grid[0]): s += self.grid[x][y] return s def diagonalSum(self, value: int) -> int: return self.cal(value, 1) # Your neighborSum object will be instantiated and called as such: # obj = neighborSum(grid) # param_1 = obj.adjacentSum(value) # param_2 = obj.diagonalSum(value)
-
type neighborSum struct { grid [][]int d map[int][2]int dirs [2][5]int } func Constructor(grid [][]int) neighborSum { d := map[int][2]int{} for i, row := range grid { for j, x := range row { d[x] = [2]int{i, j} } } dirs := [2][5]int{ {-1, 0, 1, 0, -1}, {-1, 1, 1, -1, -1} } return neighborSum{grid, d, dirs} } func (this *neighborSum) AdjacentSum(value int) int { return this.cal(value, 0) } func (this *neighborSum) DiagonalSum(value int) int { return this.cal(value, 1) } func (this *neighborSum) cal(value, k int) int { p := this.d[value] s := 0 for q := 0; q < 4; q++ { x, y := p[0]+this.dirs[k][q], p[1]+this.dirs[k][q+1] if x >= 0 && x < len(this.grid) && y >= 0 && y < len(this.grid[0]) { s += this.grid[x][y] } } return s } /** * Your neighborSum object will be instantiated and called as such: * obj := Constructor(grid); * param_1 := obj.AdjacentSum(value); * param_2 := obj.DiagonalSum(value); */
-
class neighborSum { private grid: number[][]; private d: Map<number, [number, number]> = new Map(); private dirs: number[][] = [ [-1, 0, 1, 0, -1], [-1, 1, 1, -1, -1], ]; constructor(grid: number[][]) { for (let i = 0; i < grid.length; ++i) { for (let j = 0; j < grid[0].length; ++j) { this.d.set(grid[i][j], [i, j]); } } this.grid = grid; } adjacentSum(value: number): number { return this.cal(value, 0); } diagonalSum(value: number): number { return this.cal(value, 1); } cal(value: number, k: number): number { const [i, j] = this.d.get(value)!; let s = 0; for (let q = 0; q < 4; ++q) { const [x, y] = [i + this.dirs[k][q], j + this.dirs[k][q + 1]]; if (x >= 0 && x < this.grid.length && y >= 0 && y < this.grid[0].length) { s += this.grid[x][y]; } } return s; } } /** * Your neighborSum object will be instantiated and called as such: * var obj = new neighborSum(grid) * var param_1 = obj.adjacentSum(value) * var param_2 = obj.diagonalSum(value) */