Leetcode #74
Problem
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
My Solution:
class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
"""
- binary search first col
- when l>r
- binary search r's row
"""
rows = len(matrix)
cols = len(matrix[0])
l,r = 0, rows-1
while l <= r:
m = l + (r-l)//2
num = matrix[m][0]
if num == target:
return True
elif num > target:
r = m-1
else:
l = m+1
l2, r2 = 0, cols-1
while l2 <= r2:
m2 = l2 + (r2- l2)//2
num2 = matrix[r][m2]
if num2 == target:
return True
elif num2 > target:
r2 = m2-1
else:
l2 = m2+1
return Falseand here’s the One Pass Binary Search approach:
because the matrix is sorted row-wise and each row is sorted left-to-right, the entire matrix behaves like one big sorted array.
if we imagine flattening the matrix into a single list, the order of elements doesn’t change
this means we can run one binary search from index 0 to ROWS x COLS - 1.
for any mix index m, we can map it back to the matrix using:
- row = m // COLS
- col = m % COLS
class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
"""
- one pass binary search
"""
ROWS, COLS = len(matrix), len(matrix[0])
l, r = 0, ROWS * COLS - 1
while l <= r:
m = l + (r-l)//2
# m//COLS: how many complete rows have we passed
# m%COLS: (remainder) how far into the row are we
row, col = m // COLS, m % COLS
if matrix[row][col] == target:
return True
elif matrix[row][col] > target:
r = m-1
else:
l = m+1
return False