问答题717/1603搜索二维矩阵

编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:

  • 每行中的整数从左到右按升序排列。
  • 每行的第一个整数大于前一行的最后一个整数。

示例 1:

预览

输入: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3

输出: true

示例 2:

预览

输入: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13

输出: false

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 100
  • -104 <= matrix[i][j], target <= 104
1/** 2 * @param {number[][]} matrix 3 * @param {number} target 4 * @return {boolean} 5 */ 6var searchMatrix = function(matrix, target) { 7 8};
难度:
2022-05-06 创建

参考答案:

方法一:两次二分查找

思路

由于每行的第一个元素大于前一行的最后一个元素,且每行元素是升序的,所以每行的第一个元素大于前一行的第一个元素,因此矩阵第一列的元素是升序的。

我们可以对矩阵的第一列的元素二分查找,找到最后一个不大于目标值的元素,然后在该元素所在行中二分查找目标值是否存在。

代码

1var searchMatrix = function(matrix, target) { 2 const rowIndex = binarySearchFirstColumn(matrix, target); 3 if (rowIndex < 0) { 4 return false; 5 } 6 return binarySearchRow(matrix[rowIndex], target); 7}; 8 9const binarySearchFirstColumn = (matrix, target) => { 10 let low = -1, high = matrix.length - 1; 11 while (low < high) { 12 const mid = Math.floor((high - low + 1) / 2) + low; 13 if (matrix[mid][0] <= target) { 14 low = mid; 15 } else { 16 high = mid - 1; 17 } 18 } 19 return low; 20} 21 22const binarySearchRow = (row, target) => { 23 let low = 0, high = row.length - 1; 24 while (low <= high) { 25 const mid = Math.floor((high - low) / 2) + low; 26 if (row[mid] == target) { 27 return true; 28 } else if (row[mid] > target) { 29 high = mid - 1; 30 } else { 31 low = mid + 1; 32 } 33 } 34 return false; 35}

复杂度分析

  • 时间复杂度:O(log m + log n)=O(log mn),其中 m 和 n 分别是矩阵的行数和列数。

  • 空间复杂度:O(1)。

方法二:一次二分查找

思路

若将矩阵每一行拼接在上一行的末尾,则会得到一个升序数组,我们可以在该数组上二分找到目标元素。

代码实现时,可以二分升序数组的下标,将其映射到原矩阵的行和列上。

代码

1var searchMatrix = function(matrix, target) { 2 const m = matrix.length, n = matrix[0].length; 3 let low = 0, high = m * n - 1; 4 while (low <= high) { 5 const mid = Math.floor((high - low) / 2) + low; 6 const x = matrix[Math.floor(mid / n)][mid % n]; 7 if (x < target) { 8 low = mid + 1; 9 } else if (x > target) { 10 high = mid - 1; 11 } else { 12 return true; 13 } 14 } 15 return false; 16};

复杂度分析

  • 时间复杂度:O(log mn),其中 m 和 n 分别是矩阵的行数和列数。

  • 空间复杂度:O(1)。

结语

两种方法殊途同归,都利用了二分查找,在二维矩阵上寻找目标值。值得注意的是,若二维数组中的一维数组的元素个数不一,方法二将会失效,而方法一则能正确处理。

最近更新时间:2022-05-06

赞赏支持

题库维护不易,您的支持就是我们最大的动力!