Search in a Row-wise and Column-wise Sorted 2D Array using Divide and Conquer algorithm - GeeksforGeeks

02 Jun, 2021
Given an n x n matrix, where every row and column is sorted in increasing order. Given a key, how to decide whether this key is in the matrix. A linear time complexity is discussed in the previous post. This problem can also be a very good example for divide and conquer algorithms. Following is divide and conquer algorithm.1) Find the middle element. 2) If middle element is same as key return. 3) If middle element is lesser than key then ....3a) search submatrix on lower side of middle element ....3b) Search submatrix on right hand side.of middle element 4) If middle element is greater than key then ....4a) search vertical submatrix on left side of middle element ....4b) search submatrix on right hand side. 
Following implementation of above algorithm.  
C++
Java
Python3
C#
Javascript
// C++ program for implementation of// divide and conquer algorithm// to find a given key in a row-wise// and column-wise sorted 2D array#include<bits/stdc++.h>#define ROW 4#define COL 4using namespace std; // A divide and conquer method to// search a given key in mat[]// in rows from fromRow to toRow// and columns from fromCol to// toColvoid search(int mat[ROW][COL], int fromRow, int toRow,                    int fromCol, int toCol, int key)    {        // Find middle and compare with middle        int i = fromRow + (toRow-fromRow )/2;        int j = fromCol + (toCol-fromCol )/2;        if (mat[i][j] == key) // If key is present at middle        cout<<"Found "<< key << " at "<< i <<                            " " << j<<endl;        else        {            // right-up quarter of matrix is searched in all cases.            // Provided it is different from current call            if (i != toRow || j != fromCol)            search(mat, fromRow, i, j, toCol, key);             // Special case for iteration with 1*2 matrix            // mat[i][j] and mat[i][j+1] are only two elements.            // So just check second element            if (fromRow == toRow && fromCol + 1 == toCol)            if (mat[fromRow][toCol] == key)                cout<<"Found "<< key<< " at "<<                            fromRow << " " << toCol<<endl;             // If middle key is lesser then search lower horizontal            // matrix and right hand side matrix            if (mat[i][j] < key)            {                // search lower horizontal if such matrix exists                if (i + 1 <= toRow)                search(mat, i + 1, toRow, fromCol, toCol, key);            }             // If middle key is greater then search left vertical            // matrix and right hand side matrix            else            {                // search left vertical if such matrix exists                if (j - 1 >= fromCol)                search(mat, fromRow, toRow, fromCol, j - 1, key);            }        }    } // Driver codeint main(){    int mat[ROW][COL] = { {10, 20, 30, 40},                            {15, 25, 35, 45},                            {27, 29, 37, 48},                            {32, 33, 39, 50}};    int key = 50;    for (int i = 0; i < ROW; i++)    for (int j = 0; j < COL; j++)        search(mat, 0, ROW - 1, 0, COL - 1, mat[i][j]);    return 0;} // This code is contributed by Rajput-Ji
// Java program for implementation of divide and conquer algorithm// to find a given key in a row-wise and column-wise sorted 2D arrayclass SearchInMatrix{    public static void main(String[] args)    {        int[][] mat = new int[][] { {10, 20, 30, 40},                                    {15, 25, 35, 45},                                    {27, 29, 37, 48},                                    {32, 33, 39, 50}};        int rowcount = 4,colCount=4,key=50;        for (int i=0; i<rowcount; i++)          for (int j=0; j<colCount; j++)             search(mat, 0, rowcount-1, 0, colCount-1, mat[i][j]);    }     // A divide and conquer method to search a given key in mat[]    // in rows from fromRow to toRow and columns from fromCol to    // toCol    public static void search(int[][] mat, int fromRow, int toRow,                              int fromCol, int toCol, int key)    {        // Find middle and compare with middle        int i = fromRow + (toRow-fromRow )/2;        int j = fromCol + (toCol-fromCol )/2;        if (mat[i][j] == key) // If key is present at middle          System.out.println("Found "+ key + " at "+ i +                               " " + j);        else        {            // right-up quarter of matrix is searched in all cases.            // Provided it is different from current call            if (i!=toRow || j!=fromCol)             search(mat,fromRow,i,j,toCol,key);             // Special case for iteration with 1*2 matrix            // mat[i][j] and mat[i][j+1] are only two elements.            // So just check second element            if (fromRow == toRow && fromCol + 1 == toCol)              if (mat[fromRow][toCol] == key)                System.out.println("Found "+ key+ " at "+                                   fromRow + " " + toCol);             // If middle key is lesser then search lower horizontal            // matrix and right hand side matrix            if (mat[i][j] < key)            {                // search lower horizontal if such matrix exists                if (i+1<=toRow)                  search(mat, i+1, toRow, fromCol, toCol, key);            }             // If middle key is greater then search left vertical            // matrix and right hand side matrix            else            {                // search left vertical if such matrix exists                if (j-1>=fromCol)                  search(mat, fromRow, toRow, fromCol, j-1, key);            }        }    }}
# Python3 program for implementation of# divide and conquer algorithm to find# a given key in a row-wise and column-wise# sorted 2D array a divide and conquer method# to search a given key in mat in rows from# fromRow to toRow and columns from fromCol to# toColdef search(mat, fromRow, toRow, fromCol, toCol, key):     # Find middle and compare with middle    i = fromRow + (toRow - fromRow) // 2;    j = fromCol + (toCol - fromCol) // 2;    if (mat[i][j] == key): # If key is present at middle        print("Found " , key , " at " , i , " " , j);    else:         # right-up quarter of matrix is searched in all cases.        # Provided it is different from current call        if (i != toRow or j != fromCol):            search(mat, fromRow, i, j, toCol, key);         # Special case for iteration with 1*2 matrix        # mat[i][j] and mat[i][j+1] are only two elements.        # So just check second element        if (fromRow == toRow and fromCol + 1 == toCol):            if (mat[fromRow][toCol] == key):                print("Found " , key , " at " , fromRow , " " , toCol);         # If middle key is lesser then search lower horizontal        # matrix and right hand side matrix        if (mat[i][j] < key):             # search lower horizontal if such matrix exists            if (i + 1 <= toRow):                search(mat, i + 1, toRow, fromCol, toCol, key);         # If middle key is greater then search left vertical        # matrix and right hand side matrix        else:                         # search left vertical if such matrix exists            if (j - 1 >= fromCol):                search(mat, fromRow, toRow, fromCol, j - 1, key); # Driver codeif __name__ == '__main__':    mat = [[ 10, 20, 30, 40],           [15, 25, 35, 45],           [27, 29, 37, 48],           [32, 33, 39, 50]];    rowcount = 4; colCount = 4; key = 50;    for i in range(rowcount):        for j in range(colCount):            search(mat, 0, rowcount - 1, 0, colCount - 1, mat[i][j]); # This code is contributed by 29AjayKumar
// C# program for implementation of// divide and conquer algorithm// to find a given key in a row-wise// and column-wise sorted 2D arrayusing System; public class SearchInMatrix{    public static void Main(String[] args)    {        int[,] mat = new int[,] { {10, 20, 30, 40},                                    {15, 25, 35, 45},                                    {27, 29, 37, 48},                                    {32, 33, 39, 50}};        int rowcount = 4, colCount = 4, key = 50;        for (int i = 0; i < rowcount; i++)            for (int j = 0; j < colCount; j++)            search(mat, 0, rowcount - 1, 0, colCount - 1, mat[i, j]);    }     // A divide and conquer method to    // search a given key in mat[]    // in rows from fromRow to toRow    // and columns from fromCol to    // toCol    public static void search(int[,] mat, int fromRow, int toRow,                            int fromCol, int toCol, int key)    {        // Find middle and compare with middle        int i = fromRow + (toRow-fromRow )/2;        int j = fromCol + (toCol-fromCol )/2;        if (mat[i, j] == key) // If key is present at middle        Console.WriteLine("Found "+ key + " at "+ i +                            " " + j);        else        {            // right-up quarter of matrix is searched in all cases.            // Provided it is different from current call            if (i != toRow || j != fromCol)            search(mat, fromRow, i, j, toCol, key);             // Special case for iteration with 1*2 matrix            // mat[i][j] and mat[i][j+1] are only two elements.            // So just check second element            if (fromRow == toRow && fromCol + 1 == toCol)            if (mat[fromRow,toCol] == key)                Console.WriteLine("Found "+ key + " at "+                                fromRow + " " + toCol);             // If middle key is lesser then search lower horizontal            // matrix and right hand side matrix            if (mat[i, j] < key)            {                // search lower horizontal if such matrix exists                if (i + 1 <= toRow)                search(mat, i + 1, toRow, fromCol, toCol, key);            }             // If middle key is greater then search left vertical            // matrix and right hand side matrix            else            {                // search left vertical if such matrix exists                if (j - 1 >= fromCol)                search(mat, fromRow, toRow, fromCol, j - 1, key);            }        }    }} // This code has been contributed by 29AjayKumar
<script> // JavaScript program for implementation// of divide and conquer algorithm// to find a given key in a row-wise// and column-wise sorted 2D array          // A divide and conquer method to search a given key in mat    // in rows from fromRow to toRow and columns from fromCol to    // toCol    function search(mat , fromRow , toRow,                               fromCol , toCol , key)    {        // Find middle and compare with middle        var i = parseInt(fromRow + (toRow-fromRow )/2);        var j = parseInt(fromCol + (toCol-fromCol )/2);        if (mat[i][j] == key) // If key is present at middle          document.write("Found "+ key + " at "+ i +                               " " + j+"<br/>");        else        {            // right-up quarter of matrix is searched in all cases.            // Provided it is different from current call            if (i!=toRow || j!=fromCol)             search(mat,fromRow,i,j,toCol,key);             // Special case for iteration with 1*2 matrix            // mat[i][j] and mat[i][j+1] are only two elements.            // So just check second element            if (fromRow == toRow && fromCol + 1 == toCol)              if (mat[fromRow][toCol] == key)                document.write("Found "+ key+ " at "+                                   fromRow + " " + toCol+"<br/>");             // If middle key is lesser then search lower horizontal            // matrix and right hand side matrix            if (mat[i][j] < key)            {                // search lower horizontal if such matrix exists                if (i+1<=toRow)                  search(mat, i+1, toRow, fromCol, toCol, key);            }             // If middle key is greater then search left vertical            // matrix and right hand side matrix            else            {                // search left vertical if such matrix exists                if (j-1>=fromCol)                  search(mat, fromRow, toRow, fromCol, j-1, key);            }        }        }        var mat = [[10, 20, 30, 40],                   [15, 25, 35, 45],                   [27, 29, 37, 48],                   [32, 33, 39, 50]];        var rowcount = 4,colCount=4,key=50;        for (var i=0; i<rowcount; i++)          for (var j=0; j<colCount; j++)             search(mat, 0, rowcount-1, 0, colCount-1, mat[i][j]);              // This code contributed by umadevi9616 </script>
Output:  
Found 10 at 0 0
Found 20 at 0 1
Found 30 at 0 2
Found 40 at 0 3
Found 15 at 1 0
Found 25 at 1 1
Found 35 at 1 2
Found 45 at 1 3
Found 27 at 2 0
Found 29 at 2 1
Found 37 at 2 2
Found 48 at 2 3
Found 32 at 3 0
Found 33 at 3 1
Found 39 at 3 2
Found 50 at 3 3
Time complexity: We are given a n*n matrix, the algorithm can be seen as recurring for 3 matrices of size n/2 x n/2. Following is recurrence for time complexity 
 T(n) = 3T(n/2) + O(1) 
The solution of recurrence is O(n1.58) using Master Method. But the actual implementation calls for one submatrix of size n x n/2 or n/2 x n, and other submatrix of size n/2 x n/2.This article is contributed by Kaushik Lele. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above 
29AjayKumar
Rajput-Ji
umadevi9616
Divide and Conquer
Divide and Conquer
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Binary Search In JavaScript
Find a Fixed Point (Value equal to index) in a given array
Binary Search (bisect) in Python
K-th Element of Two Sorted Arrays
Convex Hull using Divide and Conquer Algorithm
Multiply two polynomials
Search element in a sorted matrix
Median of an unsorted array using Quick Select Algorithm
Decrease and Conquer
Write you own Power without using multiplication(*) and division(/) operators