Given an integer n and an n × n matrix, check whether the matrix is a Magic Square or not. A Magic Square is a matrix containing distinct elements from 1 to n * n such that the sum of every row, every column, and both diagonals is the same.
Input: mat = [[1, 2], [3, 4]] Output: "Not a Magic Square" Explanation:
Input: mat = [[1, 1, 1], [1, 1, 1], [1, 1, 1]] Output: "Not a Magic Square" Explanation: All sums are same but all elements from 1 to n * nare not present.
[Naive Approach] Using Diagonal and Row-Column Sum Verification - O(n * n) Time and O(n * n) Space
Use a boolean array to track visited items for uniqueness (all numbers from 1 to n*n should appear once)
Compute sum of first row (let us call this sum as target) so that we can match it later with every row, column and diagonal
Traverse the matrix and compute row and column sums and compare with the target. If not same, then return false. Also check if a visited item appears again, then return false.
Traverse both diagonals and compare the sums with the target sum.
C++
#include<iostream>#include<vector>usingnamespacestd;boolisMagicSquare(vector<vector<int>>&mat){intn=mat.size();inttarget=0;// first row sumfor(intj=0;j<n;j++)target+=mat[0][j];// track uniquenessvector<int>visited(n*n+1,0);for(inti=0;i<n;i++){introwSum=0,colSum=0;for(intj=0;j<n;j++){rowSum+=mat[i][j];colSum+=mat[j][i];intval=mat[i][j];// range + duplicate checkif(val<1||val>n*n||visited[val])returnfalse;visited[val]=1;}if(rowSum!=target||colSum!=target)returnfalse;}intd1=0,d2=0;// diagonalsfor(inti=0;i<n;i++){d1+=mat[i][i];d2+=mat[i][n-i-1];}returnd1==target&&d2==target;}intmain(){vector<vector<int>>mat={{2,7,6},{9,5,1},{4,3,8}};cout<<(isMagicSquare(mat)?"Magic Square":"Not a Magic Square");return0;}
Java
publicclassGFG{publicstaticbooleanisMagicSquare(int[][]mat){intn=mat.length;inttarget=0;// Compute target sum (first row)for(intj=0;j<n;j++)target+=mat[0][j];// track valuesint[]visited=newint[n*n+1];for(inti=0;i<n;i++){introwSum=0,colSum=0;for(intj=0;j<n;j++){rowSum+=mat[i][j];colSum+=mat[j][i];intval=mat[i][j];// check range + duplicateif(val<1||val>n*n||visited[val]==1)returnfalse;visited[val]=1;}// validate row & columnif(rowSum!=target||colSum!=target)returnfalse;}intd1=0,d2=0;// diagonal sumsfor(inti=0;i<n;i++){d1+=mat[i][i];d2+=mat[i][n-i-1];}returnd1==target&&d2==target;}publicstaticvoidmain(String[]args){int[][]mat={{2,7,6},{9,5,1},{4,3,8}};System.out.println(isMagicSquare(mat)?"Magic Square":"Not a Magic Square");}}
Python
defis_magic_square(mat):n=len(mat)# first row sumtarget=sum(mat[0])# track valuesvisited=[0]*(n*n+1)foriinrange(n):row_sum=0col_sum=0forjinrange(n):row_sum+=mat[i][j]col_sum+=mat[j][i]val=mat[i][j]# check range and duplicateifval<1orval>n*norvisited[val]:returnFalsevisited[val]=1# validate row & columnifrow_sum!=targetorcol_sum!=target:returnFalse# diagonal sumsd1=sum(mat[i][i]foriinrange(n))d2=sum(mat[i][n-i-1]foriinrange(n))returnd1==targetandd2==targetif__name__=="__main__":mat=[[2,7,6],[9,5,1],[4,3,8]]print("Magic Square"ifis_magic_square(mat)else"Not a Magic Square")
C#
usingSystem;classGFG{staticboolIsMagicSquare(int[,]mat){intn=mat.GetLength(0);inttarget=0;// Compute target sum (first row)for(intj=0;j<n;j++)target+=mat[0,j];// track valuesint[]visited=newint[n*n+1];for(inti=0;i<n;i++){introwSum=0,colSum=0;for(intj=0;j<n;j++){rowSum+=mat[i,j];colSum+=mat[j,i];intval=mat[i,j];// check valid range + duplicateif(val<1||val>n*n||visited[val]==1)returnfalse;visited[val]=1;}// validate row & columnif(rowSum!=target||colSum!=target)returnfalse;}intd1=0,d2=0;// diagonal checkfor(inti=0;i<n;i++){d1+=mat[i,i];d2+=mat[i,n-i-1];}returnd1==target&&d2==target;}staticvoidMain(){int[,]mat={{2,7,6},{9,5,1},{4,3,8}};Console.WriteLine(IsMagicSquare(mat)?"Magic Square":"Not a Magic Square");}}
JavaScript
functionisMagicSquare(mat){letn=mat.length;// first row sumlettarget=mat[0].reduce((a,b)=>a+b,0);// track valuesletvisited=newArray(n*n+1).fill(0);for(leti=0;i<n;i++){letrowSum=0,colSum=0;for(letj=0;j<n;j++){rowSum+=mat[i][j];colSum+=mat[j][i];letval=mat[i][j];// check range and duplicateif(val<1||val>n*n||visited[val])returnfalse;visited[val]=1;}// validate row & columnif(rowSum!==target||colSum!==target)returnfalse;}letd1=0,d2=0;// diagonal sumsfor(leti=0;i<n;i++){d1+=mat[i][i];d2+=mat[i][n-i-1];}returnd1===target&&d2===target;}// Driver Codeletmat=[[2,7,6],[9,5,1],[4,3,8]];console.log(isMagicSquare(mat)?"Magic Square":"Not a Magic Square");
Output
Magic Square
[Expected Approach] Using a Single Pass - O(n * n) Time and O(n * n) Space
This is mainly an optimization over the above approach. Instead of doing one more iteration for diagonals, we update diagonal sums during traversal when i == j and i + j == n - 1 . Note that all main diagonal elements have i == j and all other diagonal elements have i + j == n-1. One more optimization we make is, we can compute the target as n * (n*n + 1) / 2. For a magic square.
How does the sum formula work? Sum of all numbers is 1 + 2 + 3, ... n2 which is equal to n2 × (n2 + 1)/2 [We have simply applied natural number sum formula for n = n2]. Now a magic square contains n divisions of the target sum (row wise or column wise sum), so we can write n x target = n2 × (n2 + 1)/2. From this expression, we can derive, target = n × (n2 + 1)/2
C++
#include<iostream>#include<vector>usingnamespacestd;boolisMagicSquare(vector<vector<int>>&mat){intn=mat.size();inttarget=n*(n*n+1)/2;// track uniquenessvector<int>visited(n*n+1,0);intd1=0,d2=0;for(inti=0;i<n;i++){introwSum=0,colSum=0;for(intj=0;j<n;j++){intvalRow=mat[i][j];intvalCol=mat[j][i];// range + duplicate checkif(valRow<1||valRow>n*n||visited[valRow])returnfalse;visited[valRow]=1;rowSum+=valRow;colSum+=valCol;// diagonalsif(i==j)d1+=valRow;if(i+j==n-1)d2+=valRow;}if(rowSum!=target||colSum!=target)returnfalse;}returnd1==target&&d2==target;}intmain(){vector<vector<int>>mat={{2,7,6},{9,5,1},{4,3,8}};cout<<(isMagicSquare(mat)?"Magic Square":"Not a Magic Square");return0;}
Java
importjava.util.Scanner;publicclassGFG{staticbooleanisMagicSquare(int[][]mat){intn=mat.length;inttarget=n*(n*n+1)/2;boolean[]visited=newboolean[n*n+1];intd1=0,d2=0;for(inti=0;i<n;i++){introwSum=0,colSum=0;for(intj=0;j<n;j++){intvalRow=mat[i][j];intvalCol=mat[j][i];// range + duplicate checkif(valRow<1||valRow>n*n||visited[valRow])returnfalse;visited[valRow]=true;rowSum+=valRow;colSum+=valCol;// diagonalsif(i==j)d1+=valRow;if(i+j==n-1)d2+=valRow;}if(rowSum!=target||colSum!=target)returnfalse;}returnd1==target&&d2==target;}publicstaticvoidmain(String[]args){int[][]mat={{2,7,6},{9,5,1},{4,3,8}};System.out.println(isMagicSquare(mat)?"Magic Square":"Not a Magic Square");}}
Python
defis_magic_square(mat):n=len(mat)target=n*(n*n+1)//2visited=[0]*(n*n+1)d1=d2=0foriinrange(n):row_sum=col_sum=0forjinrange(n):val_row=mat[i][j]val_col=mat[j][i]# range + duplicate checkifval_row<1orval_row>n*norvisited[val_row]:returnFalsevisited[val_row]=1row_sum+=val_rowcol_sum+=val_col# diagonalsifi==j:d1+=val_rowifi+j==n-1:d2+=val_rowifrow_sum!=targetorcol_sum!=target:returnFalsereturnd1==targetandd2==targetif__name__=="__main__":mat=[[2,7,6],[9,5,1],[4,3,8]]print("Magic Square"ifis_magic_square(mat)else"Not a Magic Square")
C#
usingSystem;classGFG{staticboolIsMagicSquare(int[,]mat){intn=mat.GetLength(0);inttarget=0;// Compute target sum (first row)for(intj=0;j<n;j++)target+=mat[0,j];// track valuesint[]visited=newint[n*n+1];for(inti=0;i<n;i++){introwSum=0,colSum=0;for(intj=0;j<n;j++){rowSum+=mat[i,j];colSum+=mat[j,i];intval=mat[i,j];// check valid range + duplicateif(val<1||val>n*n||visited[val]==1)returnfalse;visited[val]=1;}// validate row & columnif(rowSum!=target||colSum!=target)returnfalse;}intd1=0,d2=0;// diagonal checkfor(inti=0;i<n;i++){d1+=mat[i,i];d2+=mat[i,n-i-1];}returnd1==target&&d2==target;}staticvoidMain(){int[,]mat={{2,7,6},{9,5,1},{4,3,8}};Console.WriteLine(IsMagicSquare(mat)?"Magic Square":"Not a Magic Square");}}
JavaScript
functionisMagicSquare(mat){constn=mat.length;consttarget=n*(n*n+1)/2;constvisited=newArray(n*n+1).fill(false);letd1=0,d2=0;for(leti=0;i<n;i++){letrowSum=0,colSum=0;for(letj=0;j<n;j++){letvalRow=mat[i][j];letvalCol=mat[j][i];// range + duplicate checkif(valRow<1||valRow>n*n||visited[valRow])returnfalse;visited[valRow]=true;rowSum+=valRow;colSum+=valCol;// diagonalsif(i===j)d1+=valRow;if(i+j===n-1)d2+=valRow;}// validate row & columnif(rowSum!==target||colSum!==target)returnfalse;}returnd1===target&&d2===target;}// Driver Codeconstmat=[[2,7,6],[9,5,1],[4,3,8]];console.log(isMagicSquare(mat)?"Magic Square":"Not a Magic Square");