Amazon Interview Question
Software Engineer / DevelopersNo, its not correct. you can have more than one i(row ) where a[i][0] <elem and elem can be in any one of the row.
Better approach will be, search diagonally i.e.
int i =1;
for(i=1;i<N ;i++){
if(a[i][i] >elem)
break;
}
Now search the elem between a[i][1] to a[i][i], and a[1][i] to a[i][i] .
ps. element searching for could be present in the diagonal. So also consider that case
Lets say for this 2D matrix:
Integer[][] arr = new Integer[][]{
{1,5,20,21},
{2,6,39,40},
{3,7,40,41},
};
we write the code as:
private void haselement(int row, int column,int element){
if(row < 0 || column > 3){
System.out.println("The element does not exist " + element);
System.exit(0);
}
if(arr[row][column] == element){
System.out.println("The element exists " + element);
}else if (element < arr[row][column]){
haselement(row - 1, column, element);
}else{
haselement(row, column + 1, element);
}
}
Call it using:
obj.haselement(2,0,21);
Complexity: O(log n)
As you will search only one half of the matrix and not the whole
Where n = rows + columns
I have tried this code and it works. please correct me if I am wrong!!!!
Could you please generalize the solution. Are you calling this method with initial row =2 because its the middle one?
How come its O(log n). what if the element is in last row and last column?
Well to start with imagine the matrix as a KIND OF binary tree (not exactly binary tree) and the element in the last row first column as the root so that element in the above example is 3 (position = (2,0))
All the elements above 3 in the same column have values smaller than 3 and all the elements to the right of 3 in the same row have greater elements than 3
Row starts from 0 and ends at 2
Column starts from 0 and ends at 3
No lets say we are searching for 21 (element in the last row first column
we start with:
Step: 1
Row: 2 Column 0 Element 3
Compare 21 > 3
Increment column
Step: 2
Row: 2 Column 1 Element 7
Compare 21 > 7
Increment column
Step: 3
Row: 2 Column 2 Element 40
Compare 21 < 40
Decrement row
Step: 4
Row: 1 Column 2 Element 39
Compare 21 < 39
Decrement row
Step: 5
Row: 0 Column 2 Element 20
Compare 21 > 20
Increment column
Step:6
Row: 0 Column 3 Element 21
and we find the element.
we follow this path 3 -> 7 -> 40 -> 39 -> 20 -> 21
The matrix which i was talking about is this:
Integer[][] arr = new Integer[][]{
{1,5,20,21},
{2,6,39,40},
{3,7,40,41},
};
I strongly agree with your approach.
But the complexity is O(n+m) where n = # rows, m = # cols. The reason is the searched element could be in row=1,col=m position, and your started at row=n,col=1; so total traverse is n+m-2 at max. At each iteration you are traversing one position.
Agreed with the complexity issue it is O(n+m) and not O(log n). But the approach seems right and as if the questiom said it to solve in O(n) time so it solves the purpose
why would you want to do that? When i clearly mentioned that start from the last row first column for any given matrix. Coz this matrix has 3 rows (0,1,2) I have started from 2 (which actually represents the third row)
Does this solve ur doubt??
As far as I see, this is a difficult problem. Even to traverse an array it takes O(n2) so its not simple to search an element in O(n). But I think I got some kind of solution, not sure if its O(n) though. Also one assumption we have to make is all the values below a row are greater than the current rows values. Otherwise there is no way we can find a solution less than O(n2).
Also to simplify further I considered only square matrices, since this solution is working it should not be super difficult to convert it into a non-square matrix.
My idea is search for the element on diagnol elements if not found narrow down to the two rows between which the element could exist. then perform a linear search on the rows. Since we are searching only two rows this should be O(n).
//Assuming that the matrix is square m=n
//Assuming no row i+1 has an element lower than i
The scaffold for the funtion:
int[,] mat3 = new int[,] { {1,2,3,4,5},
{6,7,8,9,10},
{11,12,13,14,15},
{16,17,18,19,20},
{21,22,23,24,25},
};
int[,] mat2 = new int[,] { {1,2,3,4},
{6,7,8,9},
{11,12,13,14},
{16,17,18,19},
};
int[] pos = p.Search2DSortedSquareMatrix(mat3, 3);
if(pos.Lenght==2)
Console.Write("x {0} y {1}", pos[0], pos[1]);
public int[] Search2DSortedSquareMatrix(int[,] mat, int x)
{
int[] op=new int[2];
int m = mat.GetLength(0);
int mid = m/2; //1 to get ceiling
bool minflag=false, maxflag=false;
int x1=0,y1=0;
while ((!minflag || !maxflag) && mid > 0 && mid < m)
{
if (mat[mid, mid] == x)
{
op[0] = mid; op[1] = mid;
return op;
}
else if (mat[mid, mid] < x)
{
minflag = true;
op[0] = mid;
mid++;
}
else if (mat[mid, mid] > x)
{
maxflag = true;
op[1] = mid;
mid--;
}
}
//Linear search this loop can further be improved but I am not able to figure out now.
for(int i=op[0];i<=op[1];i++)
for(int j=0;j<m;j++)
if (mat[i, j] == x)
{
op[0] = i; op[1] = j;
return op;
}
return null;
}
@prolific.coder
Please see the solution posted just above you
that's excellent approach to find given number in sorted matrix in less than O(n^2)
@Shoonya Yes that solution works too and in fact it is better than my approach in which I am doing a linear search at the end. But he failed mention lots of important things so I didn't look at his solution seriously.
1. The columns must be increasing order, i.e. no element from column i+1 can be lesser than column i. (Transpose to my assumption).
2. The reason he started at 2,0.
We can use an algorithm based on elimination. Let M and N be the number of rows and columns respectively. Lets start our search from Matrix[0][N]. Every time we decrement the column, we potentially eliminate all the elements below it in that particular column and every time we decrement the row, we potentially eliminate all the elements to the left of it in that row.
Bool SearchElement(int **Matrix, int element)
{
int row = 0, col = N-1;
while(row>M && col>0)
{
if(Matrix[row][col] == element)
return true;
else if(Matrix[row][col]>element)
col--;
else if(Matrix[row][col]<element)
row++;
}
return false;
}
public class Searchin2DArraySortedByRowandColumn {
public static void main(String args[]) {
int arr[][] = { { 1, 3, 5, 7, 9 }, { 2, 4, 6, 8, 10 },
{ 11, 13, 15, 17, 19 }, { 12, 14, 16, 18, 20 },
{ 21, 23, 25, 27, 29 } };
int search = 21;
int row = 0, col = arr[0].length - 1;
while (row < arr.length && col >= 0) {
if (arr[row][col] == search) {
System.out.println("Found" + row + " " + col);
break;
} else if (arr[row][col] > search) {
col--;
} else if (arr[row][col] < search) {
row++;
}
}
}
}
Can ny1 explain how the above mentioned solution will work for an array like
{{10,12,13,14},
{1,2,3,4}}
Say i were to search for element 3 - using above sol. i start by comparing with 14 and continue doing col--, till i reach 10 which is still greater the element to be found i.e 3. Now wat?
Search for the element in only the first column of matrix using binary search.
- d May 18, 2010Lets say if a is a n X m matrix and elem is the element, then
if a[i][0] < elem < a[i+1][0]
then do a binary search for the element in ith row between a[i][0] and a[i][m]