Given a 2-D array mat where the elements of each row are sorted in non-decreasing order, and the first element of a row is greater than the last element of the previous row (if it exists), and an integer target, determine if the target exists in the given mat or not.
Input: mat = [ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12] ], target = 8
Output: True
Explanation: The target = 8 exists in the 'mat' at index (1, 3).
Input: mat = [ [1, 2, 4], [6, 7, 8], [9, 10, 34] ], target = 78
Output: False
Explanation: The target = 78 does not exist in the 'mat'. Therefore in the output, we see 'false'.
Input: mat = [ [1, 2, 4], [6, 7, 8], [9, 10, 34] ], target = 7
The extremely naive approach is to get the answer by checking all the elements of the given matrix. So, traverse each cell of the matrix and check every element, if it is equal to the given ‘target’.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
//Function to search for a given target in matrix
bool searchMatrix(vector<vector<int>>& mat, int target) {
// Check if the matrix is empty
if (mat.empty() || mat[0].empty()) {
return false;
}
int n = mat.size();
int m = mat[0].size();
// Traverse the matrix
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (mat[i][j] == target) {
// Return true if target is found
return true;
}
}
}
// Return false if target is not found
return false;
}
};
int main() {
vector<vector<int>> matrix = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
int target = 8;
//Create an instace of Solution class
Solution sol;
bool result = sol.searchMatrix(matrix, target);
// Output the result
result ? cout << "true\n" : cout << "false\n";
return 0;
}
import java.util.*;
class Solution {
//Function to search for a given target in matrix
public boolean searchMatrix(int[][] mat, int target) {
// Check if the matrix is empty
if (mat.length == 0 || mat[0].length == 0) {
return false;
}
int n = mat.length;
int m = mat[0].length;
// Traverse the matrix
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (mat[i][j] == target) {
// Return true if target is found
return true;
}
}
}
// Return false if target is not found
return false;
}
public static void main(String[] args) {
int[][] matrix = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
int target = 8;
// Create an instance of Solution class
Solution sol = new Solution();
boolean result = sol.searchMatrix(matrix, target);
// Output the result
System.out.println(result ? "true" : "false");
}
}
class Solution:
def searchMatrix(self, mat, target):
# Check if the matrix is empty
if not mat or not mat[0]:
return False
n = len(mat)
m = len(mat[0])
# Traverse the matrix
for i in range(n):
for j in range(m):
if mat[i][j] == target:
# Return true if target is found
return True
# Return false if target is not found
return False
if __name__ == "__main__":
matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
target = 8
# Create an instance of Solution class
sol = Solution()
result = sol.searchMatrix(matrix, target)
# Output the result
print("true" if result else "false")
class Solution {
searchMatrix(mat, target) {
// Check if the matrix is empty
if (mat.length === 0 || mat[0].length === 0) {
return false;
}
let n = mat.length;
let m = mat[0].length;
// Traverse the matrix
for (let i = 0; i < n; i++) {
for (let j = 0; j < m; j++) {
if (mat[i][j] === target) {
// Return true if target is found
return true;
}
}
}
// Return false if target is not found
return false;
}
}
let matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]];
let target = 8;
// Create an instance of Solution class
let sol = new Solution();
let result = sol.searchMatrix(matrix, target);
// Output the result
console.log(result ? "true" : "false");
As each row of the given matrix is sorted, it means the first element of each row will be less than or equal to the last element of each row. Therefore, for each row, check if the target belongs to that particular row. This can be done by verifying if the target lies between the first and the last element of the row. Once the row in which the target might lie has been identified, use the binary search algorithm on that row to check if the target is actually present. If it is, return true; otherwise, return false.
#include <bits/stdc++.h>
using namespace std;
class Solution {
private:
//Fuction to perform binary search
bool binarySearch(vector<int>& mat, int target) {
int n = mat.size();
int low = 0, high = n - 1;
//Perform binary search
while (low <= high) {
int mid = (low + high) / 2;
//Return true if target is found
if (mat[mid] == target) return true;
else if (target > mat[mid]) low = mid + 1;
else high = mid - 1;
}
//Return false if target not found
return false;
}
public:
//Function to search for a given target in matrix
bool searchMatrix(vector<vector<int>>& mat, int target) {
int n = mat.size();
int m = mat[0].size();
for (int i = 0; i < n; i++) {
/*Check if there is a possibility that
the target can be found in current row*/
if (mat[i][0] <= target && target <= mat[i][m - 1]) {
/*Return result fetched
from helper function*/
return binarySearch(mat[i], target);
}
}
// Return false if target is not found
return false;
}
};
int main() {
vector<vector<int>> matrix = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
int target = 8;
//Create an instace of Solution class
Solution sol;
bool result = sol.searchMatrix(matrix, target);
// Output the result
result ? cout << "true\n" : cout << "false\n";
return 0;
}
import java.util.*;
class Solution {
// Function to perform binary search
private boolean binarySearch(int[] nums, int target) {
int n = nums.length;
int low = 0, high = n - 1;
// Perform binary search
while (low <= high) {
int mid = (low + high) / 2;
// Return true if target is found
if (nums[mid] == target) return true;
else if (target > nums[mid]) low = mid + 1;
else high = mid - 1;
}
// Return false if target not found
return false;
}
// Function to search for a given target in matrix
public boolean searchMatrix(int[][] mat, int target) {
int n = mat.length;
int m = mat[0].length;
for (int i = 0; i < n; i++) {
/* Check if there is a possibility that
the target can be found in current row*/
if (mat[i][0] <= target && target <= mat[i][m - 1]) {
/* Return result fetched
from helper function*/
return binarySearch(mat[i], target);
}
}
// Return false if target is not found
return false;
}
public static void main(String[] args) {
int[][] matrix = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
int target = 8;
// Create an instance of Solution class
Solution sol = new Solution();
boolean result = sol.searchMatrix(matrix, target);
// Output the result
System.out.println(result ? "true" : "false");
}
}
class Solution:
# Function to perform binary search
def binarySearch(self, nums, target):
n = len(nums)
low, high = 0, n - 1
# Perform binary search
while low <= high:
mid = (low + high) // 2
# Return true if target is found
if nums[mid] == target:
return True
elif target > nums[mid]:
low = mid + 1
else:
high = mid - 1
# Return false if target not found
return False
# Function to search for a given target in matrix
def searchMatrix(self, mat, target):
n = len(mat)
m = len(mat[0])
for i in range(n):
""" Check if there is a possibility that
the target can be found in current row"""
if mat[i][0] <= target <= mat[i][m - 1]:
""" Return result fetched
from helper function"""
return self.binarySearch(mat[i], target)
# Return false if target is not found
return False
if __name__ == "__main__":
matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
target = 8
# Create an instance of Solution class
sol = Solution()
result = sol.searchMatrix(matrix, target)
# Output the result
print("true" if result else "false")
class Solution {
// Function to perform binary search
binarySearch(nums, target) {
let n = nums.length;
let low = 0, high = n - 1;
// Perform binary search
while (low <= high) {
let mid = Math.floor((low + high) / 2);
// Return true if target is found
if (nums[mid] === target) return true;
else if (target > nums[mid]) low = mid + 1;
else high = mid - 1;
}
// Return false if target not found
return false;
}
// Function to search for a given target in matrix
searchMatrix(mat, target) {
let n = mat.length;
let m = mat[0].length;
for (let i = 0; i < n; i++) {
/* Check if there is a possibility that
the target can be found in current row*/
if (mat[i][0] <= target && target <= mat[i][m - 1]) {
/* Return result fetched
from helper function*/
return this.binarySearch(mat[i], target);
}
}
// Return false if target is not found
return false;
}
}
let matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]];
let target = 8;
// Create an instance of Solution class
let sol = new Solution();
let result = sol.searchMatrix(matrix, target);
// Output the result
console.log(result ? "true" : "false");
The idea here is to flattent he 2-D matrix into 1-D matrix and then apply the binary seacrh algorithm on it. The resultant 1-D matrix will be of length N*M. If the 2D matrix is flattened, it will require O(N x M) time complexity and extra space to store the 1D array. In that case, the optimal solution will no longer be maintained. So, it is needed to flatten the matrix without actually doing it.
How to apply binary search on the 1D array without actually flattening the 2D matrix:low
and high
. The pointer low will point to 0 and the high will point to (NxM)-1, where N is total row and M is total column per row. It will basically define the search range.#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
//Function to search for a given target in matrix
bool searchMatrix(vector<vector<int>>& mat, int target) {
int n = mat.size();
int m = mat[0].size();
int low = 0, high = n * m - 1;
//Perform binary search
while (low <= high) {
int mid = (low + high) / 2;
//Calculate the row and column
int row = mid / m, col = mid % m;
//If target is found return true
if (mat[row][col] == target) return true;
else if (mat[row][col] < target) low = mid + 1;
else high = mid - 1;
}
// Return false if target is not found
return false;
}
};
int main() {
vector<vector<int>> matrix = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
int target = 8;
//Create an instace of Solution class
Solution sol;
bool result = sol.searchMatrix(matrix, target);
// Output the result
result ? cout << "true\n" : cout << "false\n";
return 0;
}
import java.util.*;
class Solution {
// Function to search for a given target in matrix
public boolean searchMatrix(int[][] mat, int target) {
int n = mat.length;
int m = mat[0].length;
int low = 0, high = n * m - 1;
// Perform binary search
while (low <= high) {
int mid = (low + high) / 2;
// Calculate the row and column
int row = mid / m;
int col = mid % m;
// If target is found return true
if (mat[row][col] == target) return true;
else if (mat[row][col] < target) low = mid + 1;
else high = mid - 1;
}
// Return false if target is not found
return false;
}
public static void main(String[] args) {
int[][] matrix = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
int target = 8;
// Create an instance of Solution class
Solution sol = new Solution();
boolean result = sol.searchMatrix(matrix, target);
// Output the result
System.out.println(result ? "true" : "false");
}
}
class Solution:
# Function to search for a given target in matrix
def searchMatrix(self, mat, target):
n = len(mat)
m = len(mat[0])
low, high = 0, n * m - 1
# Perform binary search
while low <= high:
mid = (low + high) // 2
# Calculate the row and column
row = mid // m
col = mid % m
# If target is found return true
if mat[row][col] == target:
return True
elif mat[row][col] < target:
low = mid + 1
else:
high = mid - 1
# Return false if target is not found
return False
if __name__ == "__main__":
matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
target = 8
# Create an instance of Solution class
sol = Solution()
result = sol.searchMatrix(matrix, target)
# Output the result
print("true" if result else "false")
class Solution {
// Function to search for a given target in matrix
searchMatrix(mat, target) {
let n = mat.length;
let m = mat[0].length;
let low = 0, high = n * m - 1;
// Perform binary search
while (low <= high) {
let mid = Math.floor((low + high) / 2);
// Calculate the row and column
let row = Math.floor(mid / m);
let col = mid % m;
// If target is found return true
if (mat[row][col] === target) return true;
else if (mat[row][col] < target) low = mid + 1;
else high = mid - 1;
}
// Return false if target is not found
return false;
}
}
let matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]];
let target = 8;
// Create an instance of Solution class
let sol = new Solution();
let result = sol.searchMatrix(matrix, target);
// Output the result
console.log(result ? "true" : "false");
Q: Why treat the matrix as a virtual 1D array?
A: Treating the matrix as a 1D array enables a single binary search over the entire dataset, reducing complexity from O(m⋅logn) to O(log(m⋅n)).
Q: How does this approach handle duplicates?
A: The algorithm works seamlessly with duplicates. It returns True for the first occurrence of the target encountered during the search.
Q: What if the target needs to be located instead of just checking its presence?
A: Modify the algorithm to return the 2D index of the target (row,col) when found, or −1 if the target does not exist.
Q: Can this approach be extended to 3D or higher-dimensional arrays?
A: For higher-dimensional arrays: Flatten the array into a 1D structure and apply binary search. Use modular arithmetic to map 1D indices to multi-dimensional coordinates.