Search in a row wise and column wise sorted matrix

Given an n x n matrix, where every row and column is sorted in increasing order. Given a number x, how to decide whether this x is in the matrix. The designed algorithm should have linear time complexity.

Thanks to devendraiiit for suggesting below approach.

1) Start with top right element
2) Loop: compare this element e with x
….i) if they are equal then return its position
…ii) e < x then move it to down (if out of bound of matrix then break return false) ..iii) e > x then move it to left (if out of bound of matrix then break return false)
3) repeat the i), ii) and iii) till you find element or returned false



/* Searches the element x in mat[][]. If the element is found, 
    then prints its position and returns true, otherwise prints 
    "not found" and returns false */
int search(int mat[4][4], int n, int x)
   int i = 0, j = n-1;  //set indexes for top right element
   while ( i < n && j >= 0 )
      if ( mat[i][j] == x )
         printf("\n Found at %d, %d", i, j);
         return 1;
      if ( mat[i][j] > x )
      else //  if mat[i][j] < x

   printf("\n Element not found");
   return 0;  // if ( i==n || j== -1 )

// driver program to test above function
int main()
  int mat[4][4] = { {10, 20, 30, 40},
                    {15, 25, 35, 45},
                    {27, 29, 37, 48},
                    {32, 33, 39, 50},
  search(mat, 4, 29);
  return 0;

Time Complexity: O(n)

The above approach will also work for m x n matrix (not only for n x n). Complexity would be O(m + n).

Please write comments if you find the above codes/algorithms incorrect, or find other ways to solve the same problem.

Writing code in comment? Please use, generate link and share the link here.

  • Guest

    Not only is the author of this article’s post optimal in that it’s O(N), but the fact that it takes only 2*N comparisons is also optimal. Simply imagine the boundary between two halves of the matrix divided by a specific target value. It might follow the diagonal from the lower left to the upper right, in which case at least N values must be checked. However, it could also hug the left and top sides, or close to them, being closer to 2*N in length. This entire boundary must be checked. Therefore, in the limit as N gets large, 2*N elements must be checked. This answer is as optimal as any we will see, except for mine :-)

    My solution is slightly better because for huge matricies, when the whole thing does not fit into cache, I move right when in the same row, rather than left. In my code, the hardware prefetch circuitry will cause my version (scanning starting in the lower left, moving to the upper right) to run faster, because I will have a better cache hit rate.

    I win!

  • Bill Cox

    All the guys posting O(log(m)) or O(log(m) + log(n)) solutions above are wrong! The original poster has the optimal answer with the O(N) solution! Consider this matrix:

    1 2 3 4 4
    2 3 4 4 6
    3 4 4 6 7
    4 4 6 7 8
    4 6 7 8 9

    Now do a search for 5. Any single element of the diagonal could be 5 legally. Unless you check them all, you can’t prove it’s not there! Since the diagonal has N elements for an NxN matrix, an optimal algorithm must have at least O(N) comparisons. Any claim of an O(log(N)) is mistaken.

    Further, the next diagonal, containing 6’s are also legal locations for a 5 to exist, so clearly 2*N-1 locations must be searched, meaning that the original algorithm posted is exactly optimal in terms of comparisons. The only improvement I would make is starting at the lower left instead of the upper right, since I’d have a better chance of a cache hit due to hardware prefetch algorithms while scanning right instead of left.

    Also, the posters who asked about using the middle element and searching the remaining 3 quadrants have a clever algorithm, but it’s slow. You have to compute the number of comparisons for a few matricies to see that picking the middle is a poor choice. The total comparisons looks like:

    1 + 3(1 + 3*(1 + 3(… + 3*(1)))…)

    For a 2×2:4
    For 4×4: 1 + 3*4 = 13 — we already know that the 2×2 takes 4
    For 8×8: 1 + 3*13 = 40
    For 16×16:121, 32×32:364, 64×64:1,093 …

    It’s polynomial, not linear. It’s growing faster than N^1.65. This is much slower than the original solution. In comparison, just doing a binary search on each row takes N*log2(N) comparisons, so the 64×64 would require 64*6 = 384, quite a bit faster than the pick the middle algorithm.

    An improvement to the pick the middle algorithm is to do a binary search on the diagonal from the upper left to lower right, and use the two adjacent values spanning the target to eliminate 1/2 of the matrix. This algorithm takes 1/2*N*log2(N) comparisons, which is twice as fast as binary search on each row, though still far from optimal, and if the matrix doesn’t fit into cache, it will thrash memory much worse than a binary search on each row.

    Improvements can be made over the original algorithm to improve cache performance. For example, storing the matrix diagonal by diagonal rather than row by row increases the odds of a cache hit a lot for random data. However, by that point, it probably makes more sense to finish sorting the table so that each row contains values greater than the previous rows, and less than the following rows, so you can do the search in O(log(N)). Also, if you know the typical queries will not be middle-ish values, then you can save some time on average with a binary search along the left and bottom edges to find a better starting point, which is faster than starting in the lower-left corner and then scanning up or right for a significant fraction of the edge, but your worst case will then be 2*N + log2(2*N) – 1 comparisons.

  • kaushik Lele

    I have written divide-and conquer method to search key in n*n matrix where rows and columns both are sorted ascending.
    Algorithm is :-
    Go for middle element.
    1) If middle element is same as key return.
    2) If middle element is lesser than key then
    2a) search submatrix on lower side of middle element (half of matrix)
    2b) Search submatrix on right hand side.of middle element (up-left quarter)
    3) If middle element is greater than key then
    3a) search vertical submatrix on left side of middle element (left vertical half)
    3b) search submatrix on right hand side. (up-left quarter)

    A picture could help it explain better. But code is also easy to understand. Find code at

    Can anyone comment is this algo is any better than above simple search; especially for large matrices ?

    • Guest

      Your algorithm is faster than the versions that recurse on 3 quadrants. At the next level, you eliminate 3/16th with 2 comparisons rather than 3/16ths with 3 comparisons. I expect this 2/3 computation effort to continue, and you should run in about 2/3rds the runtime of the guys that check all 3 quadrants. However, it’s still polynomial rather than linear in time. The original poster’s solution remains the best posted on this thread, other than picking the wrong corner to start from for cache efficiency.

  • kaushik Lele

    What is the correct code for binary search method ?

  • newCoder

    * Given an n x n matrix, where every row and column is sorted in increasing
    * order. Given a number x, how to decide whether this x is in the matrix.
    * The designed algorithm should have linear time complexity.
    * @param mat
    * @param x
    * @return
    public static boolean find(int[][] mat, int x) {

    int i = 0;
    int j = mat[0].length – 1;

    while (i = 0) {
    if (mat[i][j] == x) {
    System.out.println(“”+ i + ” ” + j);
    return true;
    } else if (mat[i][j] > x) {
    } else {
    return false;

  • numid

    The solution should be updated as it can be done in O(logM +logN) by appyling binary search for the matrix with a little modifications:
    1. search for the middle element of the matrix
    2.if the middle elemnt is less than the missing number,search the lower half
    search the upper half
    3. when u get a single row or two rows in which the search is to be performed,
    do 1 comparison with the last arr[i][n] to get the row in which the normal binary search will be performed.
    the following link have not been commented though,shows the code.

    • Lokesh

      Is there a middle element if this is not a square matrix ?

    • Jiten

      Will this work if the rows are not ordered according to their first element?

    • Kartik

      This may not work for many examples. Here the assumption is wrong. If an element is greater than the middle element, then we can discard half of the matrix, we can only discard, 1/4th of the matrix.

  • Varsha Anandani

    can someone tell the space complexity also..???

    • mahesh

      space complexity is O(1). We didn’t use any auxiliary space.

  • Pranav

    A modified approach, such that moving to down/left occurs in binary fassion.

    1) Start with top right element
    2) Loop: compare this element e with x
    ….i) if they are equal then return its position
    …ii) e x then move it to left by going to the middle (if out of bound of matrix then break return false)
    3) repeat the i), ii) and iii) till you find element or returned false

    Time Complexity:O(logn + logm)

    • aks

      complexity is O(n+m) ……at most in you are going to traverse down all rows and all columns (let’s say when element to find is the first col last element)

  • mrn
    	for(int i=0;i<=col;i++)
    			cout<<m<<" "<<i<<endl;
  • algobard

    Can you please post the recursive solution (O(n^1.53)) to this problem too?

  • Jay

    Use binary search,


    /* Paste your code here (You may delete these lines if not writing code) */
    • Ashish Ranjan Singh

      It should be in order of O(log(row))+O(log(column)) rather O(log(column))*O(log(row)).
      As time for searching for Correct row will take time in O(log(rows)) and searching for correct element in that row will take take time O(log(column)).

    • pavansrinivas

      actually it will be O(log(row*column)) which is nothing but(O(log(row)+log(column)))……this is justified because the above 2D matrix can be considered as a single sorted array with (row *column) elements and complexity of binary search in a sorted array with n elements is O(log(n)) ..

  • laddoo

    One Logic can be :

    Start searching/comparing with Diagonal Elements of the matrix:
    if(arr[i][i] == item)
    { //found the item }
    if(arr[i][i] < item && arr[i+1][i+1] > item)
    { //find the element in rest of the ith row and rest of the ith column }
    //increment “i” in loop

    All above things can be done with binary search as well.
    So,Time Complexity can be reduced to : O(log(m+n)).

  • gaurav1424

    Is there any way to do this in O(log n) ?

    /* Paste your code here (You may delete these lines if not writing code) */
  • rajat rastogi

    Use Improved binary partition method given in

    • rajat rastogi

      In this case complexity will be
      O(n) constant factor is very less.

  • Shobhit

    You can check the number with the middle element of matrix. Depending on whether it is smaller than the number we are searching or greater, we can eliminate 1/4th of the array(either top left part or bottom right part). So we are left with 3 smaller matrices of size 1/4th of the original matrix. Continue searching diagonals of these matrices and in the next step you will get 9 matrices of size 1/16 of the original. This approach will take time O(log(mn)) with log base as 4/3.

  • Venki

    Another Approach:

    We can cut down the search space by examining the diagonal elements.

    Trace the floor (ceil) value of x on the diagonal using binary search. The element ‘x’ must be in the row or column of floor (ceil) of x.

    As an example x = 29 in the above matrix, and x floor value is 25 (ceil value is 37 at [2, 2]) whose indices are (1, 1), then search in the first row and first column (Again we can use binary search here).

    There will be maximum of n elements on diagonal, and less than n elements in the reduced-matrices. Overall O(log n). The method works only on symmetric matrices.

    Can we generalize the method for asymmetric matrices? Yes, I guess.

    • Venki

      Sorry, it can only bring down the search space. We can create counter example to above method.

  • ddfd

    This question was asked at Microsoft Internship interview 2011.

  • ddfd

    I think after we find that the last element in the row is greater than the required element then we can apply a binary search on that row . Hence Complexity would be O ( m + logn) if matrix of size m x n . For this case where m = n complexity would be O(n + logn) i.e O(n)

    • Venki

      @ddfd, the method fails as the 2D array is not strictly sorted. For example consider above case where x = 29, the end elements of first two rows are greater than 29, but they don’t contain required element.

      If it is like apply binary search on every row, we end up with O(m log n) complexity.

  • shanky

    too gooood n simple solution man…..god knows what what type of algo i was trying

  • shrikant

    can we tackle this problem like a binary search, only that at each point of time we will have 4 possibilities. we start at mat[(n-1)/2][(n-1)/2], now the number can be in any of the four quadrants.

    int midi = (n-1)/2, midj=(n-1)/2;
    if(x == mat[midi][midj])
       return true;
    else if(x < mat[midi][midj-1] && x < mat[midi-1][midj])
       p = midi-1, q = midj-1;
    else if(x > mat[midi+1][midj] && x > mat[midi][midj+1])
       p = midi+1, q = midj+1;
    else if(x > mat[midi][midj-1] && x < mat[midi+1][midj])
       p = midi+1, q = midj;
    else if(x >mat[midi-1][midj] && x < mat[midi][midj+1])
       p = midi-1, q = midj;

    please let me know if this should work.

    • Sandeep

      @shrikant: The approach should work, but the time complexity of this approach would be more than O(n). See the below comments from @Kartik and @Vamshi.

  • shiv


  • Vamshi

    One algorithm that i could come up with is as below.

    1. Let A be the n*n array.
    2. Report the element doesn’t exist in the array, if the search element e doesn’t satisfy the condition A[1,1] <= e <= A[n,n]
    3. If n = 1, return true if the element in the array is same as search element.
    3. Consider A[n,n] as a set of 4 subarrays of sizes n/2*n/2 and recursively search in them using the same algorithm.

    At any given time, out of the four subarrays the recursive search will exit at the step 2 itself atleast for one array.
    So, in the worst case, the complexity is like T(n) = 3T(n/4) + constant time which is strictly less than O(n^2).

    Any thoughts?

    • kartik

      @Vamsi: The algo proposed by you is simple and good!

      I think the time complexity should be T(n) = 3T(n/2) + C. The subproblems are of size n/2. It is still less than O(n^2) though.

      • Vamshi

        @kartik: I realised my mistake now.

        The complexity of this algorithm will be now n^3/2. But the algorithm mentioned in the post is far better than this one as it is of linear time.

        • Satyanarayana Batchu

          I think time complexity is T(n) = 3 T(n/4) + C.

          Then time complexity should be T(n) = n Pow log 3 base 4. i.e n Pow 0.602

          This is far less than O(n), so this algorithm is better

          • Kartik

            No, it is n/2.

            Original matrix size was n*n. The reduced matrix size is n/2*n/2

  • reg_frenzy

    Also, another optimization could be applied, extending the idea of girish. We could check if the element to be searched is lesser or greater than Matrix[n/2][n/2]. Depending on that we could make either the top right element or the bottom right element as the start element as the start element. This way, we effectively need to search only half the matrix.

    This could also be extended recursively, searching half the arrays, every time.

  • ynnus4u

    another approach: given n x m matrix A[]][],find x, complexity O(log (min(m,n)))

    Assume n < m, do binary search on 1st column & find the smallest element that is still larger than X.
    Say it's gonna be A[i,0]. Now throw all rows after and including i (since X is smaller than all of these elements).
    Repeat for a smaller matrix of size (i-1, m – 1) by proceeding to next column.

    Proof of complexity : effectively we are searching along an array of size m, time complexity = O(log n)

  • Venki

    Given below are related posts,

    @Vick‘s method seems to be feasible (I haven’t tried). On big 2D arrays it may be worth considering.

    I closed all of them to consolidate any further comments here.

    • girish.khadke

      Two conditions are missing and code can be optimized to handle those too:

      int search(int mat[4][4], int n, int x)
         if(x <a> a[n][n]) return -1;  //Or return some exception code
         int i = 0, j = n-1;  //set indexes for top right element
         while ( i = 0 )
            if ( mat[i][j] == x )
               printf("\n Found at %d, %d", i, j);
               return 1;
            if ( mat[i][j] > x )
            else //  if mat[i][j] < x
         printf("\n Element not found");
         return 0;  // if ( i==n || j== -1 )
      • girish.khadke

        Sorry can not get code part properly.

        Check if x is less than a[0][0] or greater than a[n][n] and return exception in this case, since we do not have to search such number in array anymore due to sorted order of matrix.