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 of value, that is either to the top, left, right, or bottom of value in grid.
int diagonalSum(int value) returns the sum of elements which are diagonal neighbors of value, that is either to the top-left, top-right, bottom-left, or bottom-right of value in grid.
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 in adjacentSum and diagonalSum will be in the range [0, n2 - 1].
At most 2 * n2 calls will be made to adjacentSum and diagonalSum.
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)$.
classNeighborSum:def__init__(self,grid:List[List[int]]):self.grid=gridself.d={}self.dirs=((-1,0,1,0,-1),(-1,1,1,-1,-1))fori,rowinenumerate(grid):forj,xinenumerate(row):self.d[x]=(i,j)defadjacentSum(self,value:int)->int:returnself.cal(value,0)defcal(self,value:int,k:int):i,j=self.d[value]s=0fora,binpairwise(self.dirs[k]):x,y=i+a,j+bif0<=x<len(self.grid)and0<=y<len(self.grid[0]):s+=self.grid[x][y]returnsdefdiagonalSum(self,value:int)->int:returnself.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)
classNeighborSum{privateint[][]grid;privatefinalMap<Integer,int[]>d=newHashMap<>();privatefinalint[][]dirs={{-1,0,1,0,-1},{-1,1,1,-1,-1}};publicNeighborSum(int[][]grid){this.grid=grid;intm=grid.length,n=grid[0].length;for(inti=0;i<m;++i){for(intj=0;j<n;++j){d.put(grid[i][j],newint[]{i,j});}}}publicintadjacentSum(intvalue){returncal(value,0);}publicintdiagonalSum(intvalue){returncal(value,1);}privateintcal(intvalue,intk){int[]p=d.get(value);ints=0;for(intq=0;q<4;++q){intx=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];}}returns;}}/** * 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); */
classNeighborSum{public:NeighborSum(vector<vector<int>>&grid){this->grid=grid;intm=grid.size(),n=grid[0].size();for(inti=0;i<m;++i){for(intj=0;j<n;++j){d[grid[i][j]]={i,j};}}}intadjacentSum(intvalue){returncal(value,0);}intdiagonalSum(intvalue){returncal(value,1);}private:vector<vector<int>>grid;unordered_map<int,pair<int,int>>d;intdirs[2][5]={{-1,0,1,0,-1},{-1,1,1,-1,-1}};intcal(intvalue,intk){auto[i,j]=d[value];ints=0;for(intq=0;q<4;++q){intx=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];}}returns;}};/** * 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); */
typeNeighborSumstruct{grid[][]intdmap[int][2]intdirs[2][5]int}funcConstructor(grid[][]int)NeighborSum{d:=map[int][2]int{}fori,row:=rangegrid{forj,x:=rangerow{d[x]=[2]int{i,j}}}dirs:=[2][5]int{{-1,0,1,0,-1},{-1,1,1,-1,-1}}returnNeighborSum{grid,d,dirs}}func(this*NeighborSum)AdjacentSum(valueint)int{returnthis.cal(value,0)}func(this*NeighborSum)DiagonalSum(valueint)int{returnthis.cal(value,1)}func(this*NeighborSum)cal(value,kint)int{p:=this.d[value]s:=0forq:=0;q<4;q++{x,y:=p[0]+this.dirs[k][q],p[1]+this.dirs[k][q+1]ifx>=0&&x<len(this.grid)&&y>=0&&y<len(this.grid[0]){s+=this.grid[x][y]}}returns}/** * Your NeighborSum object will be instantiated and called as such: * obj := Constructor(grid); * param_1 := obj.AdjacentSum(value); * param_2 := obj.DiagonalSum(value); */
classNeighborSum{privategrid:number[][];privated:Map<number,[number,number]>=newMap();privatedirs:number[][]=[[-1,0,1,0,-1],[-1,1,1,-1,-1],];constructor(grid:number[][]){for(leti=0;i<grid.length;++i){for(letj=0;j<grid[0].length;++j){this.d.set(grid[i][j],[i,j]);}}this.grid=grid;}adjacentSum(value:number):number{returnthis.cal(value,0);}diagonalSum(value:number):number{returnthis.cal(value,1);}cal(value:number,k:number):number{const[i,j]=this.d.get(value)!;lets=0;for(letq=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];}}returns;}}/** * 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) */