Google Interview Question
Software Engineer / DevelopersCountry: United States
Interview Type: In-Person
Matrix inversion is not recommended, it takes more time than Gaussian elimination, which reduces the matrix to a triangular one:
// put the numbers in matrix m, row i-1 contains ai bi ci xi, n=3
for(int i=0; i < n; i ++)
for(int r=i+1; r < n; r ++) { // row
k = m[r][i] / m[i][i];
for(int c=i; c < n+1; c++) // column
m[r][c] -= k * m[i][c];
}
From this matrix you can get x1..xn as result[0..n-1]:
for(int i=n-1; i >= 0; i--) {
r = m[i][n]; // right side of the equation
for(int j=n-1; j > i; j --)
r -= m[i][j] * result[j];
result[i] = r / m[i][i];
}
public static function solveMatrix(a:Array, b:Array, X:Array):void
{
var invA:Array = [];
invA[0] = [];
invA[1] = [];
invA[2] = [];
var invDet:Number = 1/((a[0][0]*(a[2][2]*a[1][1]-a[2][1]*a[1][2]))-(a[1][0]*(a[2][2]*a[0][1]-a[2][1]*a[0][2]))+(a[2][0]*(a[1][2]*a[0][1]-a[1][1]*a[0][2])));
invA[0][0] = invDet * (a[2][2]*a[1][1]-a[2][1]*a[1][2]);
invA[0][1] = invDet * (-1 * (a[2][2]*a[0][1]-a[2][1]*a[0][2]));
invA[0][2] = invDet * (a[1][2]*a[0][1]-a[1][1]*a[0][2]);
invA[1][0] = invDet * (-1 * (a[2][2]*a[1][0]-a[2][0]*a[1][2]));
invA[1][1] = invDet * (a[2][2]*a[0][0]-a[2][0]*a[0][2]);
invA[1][2] = invDet * (-1 * (a[1][2]*a[0][0]-a[1][0]*a[0][2]));
invA[2][0] = invDet * (a[2][1]*a[1][0]-a[2][0]*a[1][1]);
invA[2][1] = invDet * (-1 * (a[2][1]*a[0][0]-a[2][0]*a[0][1]));
invA[2][2] = invDet * (a[1][1]*a[0][0]-a[1][0]*a[0][1]);
X[0] = invA[0][0] * b[0] + invA[0][1] * b[1] + invA[0][2] * b[2];
X[1] = invA[1][0] * b[0] + invA[1][1] * b[1] + invA[1][2] * b[2];
X[2] = invA[2][0] * b[0] + invA[2][1] * b[1] + invA[2][2] * b[2];
}
This is still HS math. You just don't know your linear algebra well enough.
Step 1) do a determination test (write a 3x3 det function, please don't tell me you can't even write an expression) If it is 0. It may have 0 or infinite solution
Step 2) Applied row reduction, but if det is not zero, you can divide the first row and make a[0][0] = 1. Then make a[0][1] = a[0][2] = 0, then make a[1][1] = 1 and a[0][1] = a[0][2] = 0, and do it for a[2] (maybe I indexed it backward from yours? whatever that is not the point). Then you finished row reduction and have the unique solution.
main(){
det = computeDet();
computeAdj();
for(int i=0;i<3;i++){
System.out.println();
for(int j=0;j<3;j++){
result[i][j] = result[i][j]/det;
}
}
x1 = d1*result[0][0] + d2*result[0][1] + d3*result[0][2];
x2 = d1*result[1][0] + d2*result[1][1] + d3*result[1][2];
x3 = d1*result[2][0] + d2*result[2][1] + d3*result[2][2];
System.out.println((int)x1+" "+(int)x2+" "+(int)x3);
}
public static int computeDet(){
int sum = 0;
for(int i=0,j=0;j<3;j++){
sum = sum + abc[i][j]*((abc[(i+1)%3][(j+1)%3]*abc[(i+2)%3][(j+2)%3])-(abc[(i+2)%3][(j+1)%3]*abc[(i+1)%3][(j+2)%3]));
}
return sum;
}
public static void computeAdj(){
int[][] mTrans = {{1,0,0},{0,1,0},{0,0,0}};
for(int i=0;i<2;i++){
for(int j=i;j<2;j++){
mTrans[i][j+1] = abc[j+1][i];
mTrans[j+1][i] = abc[i][j+1];
}
}
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
adj[i][j] = (mTrans[(i+1)%3][(j+1)%3]*mTrans[(i+2)%3][(j+2)%3])-(mTrans[(i+2)%3][(j+1)%3]*mTrans[(i+1)%3][(j+2)%3]);
}
}
}
O(n^2). Messed up eh! this is what I would have given.
Not a programmer - Hence Pseudo code.
MAX = 3 (can be changed to use higher numbers)
results are in d[MAX]
a,b,c values are in abc[3,MAX]
abc[1] = "a1,a2,a3"
abc[2] = "b1,b2,b3"
abc[3] = "c1,c2,c3"
x = "x1,x2,x3"
for i = 1 to MAX
for j = 1 to MAX
index = j \ (MAX + 1) ======> Assuming that this returns the remainder
d[index]=d[index] + abc[i,1] * x[index]
endfor
endfor
- Anil June 07, 2013