Welcome to Subscribe On Youtube
74. Search a 2D Matrix
Description
You are given an m x n
integer matrix matrix
with the following two properties:
- Each row is sorted in non-decreasing order.
- The first integer of each row is greater than the last integer of the previous row.
Given an integer target
, return true
if target
is in matrix
or false
otherwise.
You must write a solution in O(log(m * n))
time complexity.
Example 1:
Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3 Output: true
Example 2:
Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13 Output: false
Constraints:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 100
-104 <= matrix[i][j], target <= 104
Solutions
Solution 1: Binary Search
We can logically unfold the two-dimensional matrix and then perform binary search.
The time complexity is $O(\log(m \times n))$, where $m$ and $n$ are the number of rows and columns of the matrix, respectively. The space complexity is $O(1)$.
Solution 2: Search from the Bottom Left or Top Right
Here, we start searching from the bottom left corner and move towards the top right direction. We compare the current element $matrix[i][j]$ with $target$:
- If $matrix[i][j] = target$, we have found the target value and return
true
. - If $matrix[i][j] > target$, all elements to the right of the current position in this row are greater than target, so we should move the pointer $i$ upwards, i.e., $i = i - 1$.
- If $matrix[i][j] < target$, all elements above the current position in this column are less than target, so we should move the pointer $j$ to the right, i.e., $j = j + 1$.
If we still can’t find $target$ after the search, return false
.
The time complexity is $O(m + n)$, where $m$ and $n$ are the number of rows and columns of the matrix, respectively. The space complexity is $O(1)$.
-
class Solution { public boolean searchMatrix(int[][] matrix, int target) { int m = matrix.length, n = matrix[0].length; int left = 0, right = m * n - 1; while (left < right) { int mid = (left + right) >> 1; int x = mid / n, y = mid % n; if (matrix[x][y] >= target) { right = mid; } else { left = mid + 1; } } return matrix[left / n][left % n] == target; } }
-
class Solution { public: bool searchMatrix(vector<vector<int>>& matrix, int target) { int m = matrix.size(), n = matrix[0].size(); int left = 0, right = m * n - 1; while (left < right) { int mid = left + right >> 1; int x = mid / n, y = mid % n; if (matrix[x][y] >= target) { right = mid; } else { left = mid + 1; } } return matrix[left / n][left % n] == target; } };
-
class Solution: def searchMatrix(self, matrix: List[List[int]], target: int) -> bool: m, n = len(matrix), len(matrix[0]) left, right = 0, m * n - 1 while left <= right: # must be <=, not <, for matrax=[[1]],target=1 mid = (left + right) >> 1 x, y = divmod(mid, n) # note: divide column count if matrix[x][y] == target: return True elif matrix[x][y] > target: right = mid - 1 else: left = mid + 1 return False ########### class Solution: def searchMatrix(self, matrix: List[List[int]], target: int) -> bool: m, n = len(matrix), len(matrix[0]) left, right = 0, m * n - 1 while left < right: mid = (left + right) >> 1 x, y = divmod(mid, n) if matrix[x][y] >= target: right = mid else: left = mid + 1 return matrix[left // n][left % n] == target
-
func searchMatrix(matrix [][]int, target int) bool { m, n := len(matrix), len(matrix[0]) left, right := 0, m*n-1 for left < right { mid := (left + right) >> 1 x, y := mid/n, mid%n if matrix[x][y] >= target { right = mid } else { left = mid + 1 } } return matrix[left/n][left%n] == target }
-
function searchMatrix(matrix: number[][], target: number): boolean { const m = matrix.length; const n = matrix[0].length; let left = 0; let right = m * n; while (left < right) { const mid = (left + right) >>> 1; const i = Math.floor(mid / n); const j = mid % n; if (matrix[i][j] === target) { return true; } if (matrix[i][j] < target) { left = mid + 1; } else { right = mid; } } return false; }
-
/** * @param {number[][]} matrix * @param {number} target * @return {boolean} */ var searchMatrix = function (matrix, target) { const m = matrix.length, n = matrix[0].length; let left = 0, right = m * n - 1; while (left < right) { const mid = (left + right + 1) >> 1; const x = Math.floor(mid / n); const y = mid % n; if (matrix[x][y] <= target) { left = mid; } else { right = mid - 1; } } return matrix[Math.floor(left / n)][left % n] == target; };
-
use std::cmp::Ordering; impl Solution { pub fn search_matrix(matrix: Vec<Vec<i32>>, target: i32) -> bool { let m = matrix.len(); let n = matrix[0].len(); let mut i = 0; let mut j = n; while i < m && j > 0 { match matrix[i][j - 1].cmp(&target) { Ordering::Equal => { return true; } Ordering::Less => { i += 1; } Ordering::Greater => { j -= 1; } } } false } }