views:

302

answers:

2

I have a x by y matrix, where each row and each column are in ascending order as given below.

1   5   7    9
4   6   10   15
8   11  12   19
14  16  18   21

How to search this matrix for a number in O(x+y)?

I was asked this question for an interview, but could not figure out the way. Curious to know if it could be done.

+20  A: 

Start at the last element of the first row(top-right corner).
Compare it with the key. We have 3 cases:

  • If they are equal we are done.

  • If key is greater than that element then it means key cannot be present in that row so move the search to the element below it.

  • If key is less than that element then it means key could be present in that row towards left and cannot be present in the column further down, so move the search to the element left of it.

Keep doing it till you find the element or you cannot further move(key does not exist).

Pseudo code:

Let R be number of rows
Let C be number of columns

Let i = 0
Let j = C-1

found = 0
while( i>=0 && i<R) && (j>=0 && j<C) )
   if (matrix[i][j] == key )
      found = 1;
      break
   else if( matrix[i][j] > key )
       j--
   else if( matrix[i][j] < key )
       i++
end-while
codaddict
"If key is less than that element then it means key could be present in that row towards left" - and can't be present in the column further down, which is why it's OK to rule out ever reaching any of those cells in future.
Steve Jessop
I can't see this working. Suppose I am searching for key= 11 in the above array, how does this algo find it?
Ashley
@Ashley: We start at `9`. `11` > `9` so move down. `11` < `15` move left. `11` > `10` move down. `11` < `12` move left. `11` == `11`
codaddict
@Downvoter: Care to explain ?
codaddict
@codeaddict got it, thanks!
Ashley
@Steve: You are right. That needs to be included.
codaddict
Would've upvoted twice is I could!
Nikita Rybak
@codaddict: downvotes never explain any longer :/ This is a classic algorithm for searching in sorted matrices, the basic idea is that you sort the matrix in the direction of one diagonal and iterate along the other. You could therefore start at the lower-left corner too :)
Matthieu M.
@codeaddict : good explanation.+1 for clear explanation.
saurabh
great answer...
giri
+4  A: 

Split the Matrix in 4 submatrices. If bottom right of a sub-matrix is less than key, discard it. If the top left of a sub-matrix is bigger than the key, discard it. Repeat the splitting procedure for the remaining sub-matrices.

[Update] For some pseudo code (and a discussion of complexity) see Jeffrey L Whitledge's answer of this question.

Landei
That should have even better performance: O(log x + log y) ?!
Andre Holzner
It might be faster, but needs more memory.
Landei
How will you split the matrix in 4 submatrices? Till when will you repeat? When will you know that the element is not present? Start writing psuedo code and you will son find that this is not that easy.@Landei - Won't the memory be same as x*y?
Manoj R
Actually, this will be O(2 ^ log x + 2 ^ log y), as at each step you need to recurse over 2 (or three, but you can improve to avoid that) sub-matrixes. This is O(x + y)
Chris Dodd