Microsoft Interview Question
Software Engineer / DevelopersTeam: Bing
Country: India
Interview Type: In-Person
yes this is the logarithmic approach. The only difference is, in a binary approach, you discard half of the input size in every pass, whereas in this one, you are discarding only 1/4th of the input in one pass. so it will log base 4 (which is a constant times log base 2). and O(log (n*n)) is same as O(log(n)) ...
if Rows are sorted left to right in ascending order. Columns are sorted top to bottom in ascending order....
This algorithm works by elimination. Every move to the left (--col) eliminates all the elements below the current cell in that column. Likewise, every move down eliminates all the elements to the left of the cell in that row.
boolean FindElem(int[][] mat, int elem, int M, int N) {
int row = 0;
int col = N-1;
while (row < M && col >= 0) {
if (mat[row][col] == elem) {
return true;
} else if (mat[row][col] > elem) {
col--;
} else {
row++;
}
}
return false;
}
Why exactly do you say this is O(N)? Say you have a 4x4 matrix (16 cells). It will take you at most 4 tries to find the answer. Same with 4x4 matrix. You need at most 5 tries to find the answer. This is O(lg N)
What makes you say this is O(N)?
In the given problem the N is given as 4 not 16. if your algo is taking 5 tries the still its in the order of N. that mean N+1.
As told by sanjay, suppose we are looking for 11,
based on diagonal search we find that 11 lies in between 8 and 12, so 11 can lie in either
[3 11
4 14]
or
[6 7
9 10]
follow same procedure for these blocks and continue.
complexity,
N + N/2 + N/2^2 .. = 0(log2(N))
Sorry, but n + n/2 + n/4 + ... is O(n) and not O(log(n)). It's quite clear that a sum that only includes positive numbers and starts with n can't be less than O(n).
Please find the complete logic..
Better then this... use the Diagonal as a shorted array... and use modified version of binary search...
1 5 6 7
2 8 9 10
3 11 12 13
4 14 15 16
the diagonal is 1 8 12 16.. use the binary search on this to find out the nearest element of the number
Diagonal which is greater then the element which had to be searched and its previous element is less then the element which is has to searched for example suppose we have to search 10 in the given matrix.... 12 is greater then the 10 and 8 is less then 10. your number will be in the row or column of either 8 or 12. search using binary search in the column and row of element 8 and 12.
searching element in Diagonal will take O(logN)
searching element in 2 row + 2 column will tale 4*logN that is log N
total complexity is in the order or log N.
Please comment if you are finding any loop hole in the logic.
Sanjay, I think the number may not be necessarily in the row/column of 8/12.
Consider this array:
1 5 6 10
2 8 9 15
3 11 12 20
4 15 16 25
Here 10 lies between 8 and 12 but, not in the row/column of 8/12.
As someone below pointed out, each time, we can only eliminate one quarter of the input. In this case, we can eliminate
1 5
2 8
Bhagwan Shri Ramchandra ki jai....
Now see the solution....
Let matrix M[1,1],M[1,2],....M[1,N]
...
...
M[N,1],M[N,2],....M[N,N]
Short Algo-
1. Do binary search on the 1st column to locate the row where x could be - O(lgN)
2. Do binary search in the found row to locate x. - O(lgN)
Detailed algo -
Step 1. // Search 1st column to get the row_num where x might belong
1.first=1, last=N
2.while(first<last) {
2.1 mid=floor((first+last)/2);
2.2 if(M[mid,1]<x), first=mid+1; flag=1
2.3 else if(M[mid,1]>x), last=mid-1; flag=2
2.4 else return(mid) //mid as row_num to be checked for x
}
3. if(flag==1) return(first-1) //first-1 as row_num to be checked for x
4. if(flag==2) return(last+1) //last+1 as row_num to be checked for x
Step 2. //Search row_no row for element x
1. first=1, last=N;
2. while(first<last) {
2.1 mid=floor((first+last)/2);
2.2 if(a[mid]<x), first=mid+1;
2.3 else if(a[mid]>x), last=mid-1;
2.4 else return(mid)) //mid as column number containing x
}
3. return(-1) // x not present
row_num,col_num = position of x
Jay bolo Shri Ram ji ki....
Ram Lakshamana Jaanki, Jay bolo Hanuman ki....
Correction:
In step 1 replace this
if(flag==1) return the number less than x, index: first or first-1
if(flag==2) return the number less than x, last or last+1
Basically when we have first=last-1, jus return one of first, last, first-1 or last+1. you can implement it way you want.
And also if x is present in the very 1st column then put this check outside while, check each of 4 indexes mentioned above for x, if so return position: row_number,1
I've found a proof that this problem is not solvable with anything better than O(n) in the worst case. Consider a special case of matrix M:
1 1 1 ... 1 (2 or 3)
1 1 ... (2 or 3) 4
1 .... (2 or 3) 4 4
.................................
1 (2 or 3) 4 4 ... 4 4
(2 or 3) 4 4 4 ... 4 4
If you are required to find, say, value "3", your task will be not easier than finding said "3" in arbitrary (not necessarily sorted) array of 2-s and 3-s. Proof: consider array of 2-s and 3-s, place it on that diagonal of matrix M, if you can find 3 faster than O(n), than you can find it in the given array too, which is apparently not possible.
Better then this... use the Diagonal as a shorted array... and use modified version of binary search...
1 5 6 7
2 8 9 10
3 11 12 13
4 14 15 16
the diagonal is 1 8 12 16.. use the binary search on this to find out the nearest element of the number and then check the adjustment element of nearest element to find out the number.
Can you explain why you believe your algo finds the element? I'm pretty sure the element isn't guaranteed to be anywhere near the diagonal.
yes I got it... find the element in the Diagonal which is greater then the element which had to be searched and its previous element is less then the element which is has to searched for example suppose we have to search 10 in the given matrix.... 12 is greater then the 10 and 8 is less then 10. your number will be in the row or column of either 8 or 12. search using binary search.
searching element in Diagonal will take O(logN)
searching element in 2 row + 2 column will tale 4*logN that is log N
total complexity is in the order or log N
In your example Sanjay, the 10 could be in the bottom left corner (where the 4 is), not just the 2 rows + 2 columns you point out.
what about using three binary search.
bool Search(int matrix[][M_SIZE], int k)
{
int start = 0, end = M_SIZE-1;
int middle;
while (start <= end)
{
middle = (start+end)/2;
if (matrix[middle][middle] == k)
return true;
else if (matrix[middle][middle] > k)
end = middle-1;
else
start = middle+1;
}
if (matrix[middle][middle] < k)
return false;
int line = middle;
// dprint(line);
start = 0, end = line;
while (start <= end)
{
middle = (start+end)/2;
if (matrix[line][middle] == k)
return true;
else if (matrix[line][middle] > k)
end = middle-1;
else
start = middle+1;
}
start = 0, end = line;
while (start <= end)
{
middle = (start+end)/2;
if (matrix[middle][line] == k)
return true;
else if (matrix[middle][line] > k)
end = middle-1;
else
start = middle+1;
}
return false;
}
Here is a O(logn) solution
1. Start with [0][0] Location and check max value of the Row and Column i.e. [0][ColMax] and [rowMax][0]
2. If the value is outside the range Move diagonally down e.g. Matrix[1][1] and Goto Step 1
If reached last diagnol then return with value not found
3. Search within the Row and Column
Moving along the diagonol is O(log(n)) . Then searching element in the row or column is O(logn) + O(log n) = O(log n). So overall it is O(log n ) algorithm where n is size of the col/row
If the matrix is sorted both on its columns and rows (and assuming the sort order is ascending for both columns and rows), you can process the matrix as a simple linear array of sorted values and use a simple binary (O(logN)) search to find the sought value or confirm that the values is missing from the matrix.
For any given mXn matrix M[0][0] and M[m][n] gives the range of the matrix
- Anonymous January 22, 20121. Divide the MATRIX into 4 submatrices.
2. For each of the 4 matrices check the range(s) and eliminate the matrices. At least one of the 4 submatrices is eliminated in this step.
3. Repeat recursively untill, submatrix consists of one element.
Recursive relation : T(n) = 3T(n/4) + O(1)
Complexity : less than O(n)