LeetCode:搜索二维矩阵题解

简介: 请写出一个高效的在m*n矩阵中判断目标值是否存在的算法,矩阵具有如下特征:每一行的数字都从左到右排序每一行的第一个数字都比上一行最后一个数字大

题干


请写出一个高效的在m*n矩阵中判断目标值是否存在的算法,矩阵具有如下特征:

每一行的数字都从左到右排序

每一行的第一个数字都比上一行最后一个数字大


用例


例如对于下面矩阵:


[

   [1,   3,  5,  9],

   [10, 11, 12, 30],

   [230, 300, 350, 500]

]


要搜索的目标值为3,返回true;

示例1

输入:


[[1,3,5,9],[10,11,12,30],[230, 300, 350, 500]],3


返回值:


true


解答


有效信息:


每一行的数字都从左到右递增

每一行的第一个数字都比上一行最后一个数字大

故此此矩阵有序,可用二分查找取值。


方法一:两次二分查找


可以先通过二分查找确定 行,再对该 行 继续进行二分查找 ,常规思维:


class Solution {

   public boolean searchMatrix(int[][] matrix, int target) {

       int rowIndex = binarySearchFirstColumn(matrix, target);

       if (rowIndex < 0) {

           return false;

       }

       return binarySearchRow(matrix[rowIndex], target);

   }

   public int binarySearchFirstColumn(int[][] matrix, int target) {

       int low = -1, high = matrix.length - 1;

       while (low < high) {

           int mid = (high - low + 1) / 2 + low;

           if (matrix[mid][0] <= target) {

               low = mid;

           } else {

               high = mid - 1;

           }

       }

       return low;

   }

   public boolean binarySearchRow(int[] row, int target) {

       int low = 0, high = row.length - 1;

       while (low <= high) {

           int mid = (high - low) / 2 + low;

           if (row[mid] == target) {

               return true;

           } else if (row[mid] > target) {

               high = mid - 1;

           } else {

               low = mid + 1;

           }

       }

       return false;

   }

}



复杂度分析

时间复杂度:

O ( log ⁡ m + log ⁡ n ) = O ( log ⁡ m n ) O ( l o g m + l o g n ) = O ( l o g m n ) O(\log m+\log n)=O(\log mn)O(logm+logn)=O(logmn)O(logm+logn)=O(logmn)O(logm+logn)=O(logmn)

其中 mm 和 nn 分别是矩阵的行数和列数。


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


方法二:一次二分查找

因为每一行的第一个数字都比上一行最后一个数字大 ,所以我们可通过 数学的方法 将其压缩为一个 一维矩阵


import java.util.*;

public class Solution {

   /**

    *

    * @param matrix int整型二维数组

    * @param target int整型

    * @return bool布尔型

    */

   public boolean searchMatrix (int[][] matrix, int target) {

       // write code here

       int M = matrix.length, N = matrix[0].length,left = 0, right = M * N - 1;

       while (left <= right) {

           int center = ( right - left) / 2 + left;

           int compute = matrix[center / N][center % N];

           if (compute < target) {

               left = center + 1;

           } else if (compute > target) {

               right = center - 1;

           } else {

               return true;

           }

       }

       return false;

   }

}



复杂度分析

时间复杂度:O(logmn),其中 m是矩阵的行 和 n 是矩阵的列

空间复杂度:O(1),原有数组上进行操作,未申请额外空间


目录
相关文章
|
6月前
|
算法 Go
【LeetCode 热题100】73:矩阵置零(详细解析)(Go语言版)
这篇文章详细解析了力扣热题 73——矩阵置零问题,提供两种解法:一是使用额外标记数组,时间复杂度为 O(m * n),空间复杂度为 O(m + n);二是优化后的原地标记方法,利用矩阵的第一行和第一列记录需要置零的信息,将空间复杂度降低到 O(1)。文章通过清晰的代码示例与复杂度分析,帮助理解“原地操作”及空间优化技巧,并推荐相关练习题以巩固矩阵操作能力。适合刷题提升算法思维!
147 9
|
存储 算法 NoSQL
LeetCode第73题矩阵置零
文章介绍了LeetCode第73题"矩阵置零"的解法,通过使用矩阵的第一行和第一列作为标记来记录哪些行或列需要置零,从而在不增加额外空间的情况下解决问题。
LeetCode第73题矩阵置零
|
12月前
|
算法 索引
LeetCode(搜索插入位置)
如何使用二分查找算法来解决LeetCode上的“搜索插入位置”问题,确保时间复杂度为O(log n),并提供了详细的代码实现和分析。
73 2
|
12月前
|
索引
Leetcode第三十三题(搜索旋转排序数组)
这篇文章介绍了解决LeetCode第33题“搜索旋转排序数组”的方法,该问题要求在旋转过的升序数组中找到给定目标值的索引,如果存在则返回索引,否则返回-1,文章提供了一个时间复杂度为O(logn)的二分搜索算法实现。
95 0
Leetcode第三十三题(搜索旋转排序数组)
LeetCode第81题搜索旋转排序数组 II
文章讲解了LeetCode第81题"搜索旋转排序数组 II"的解法,通过二分查找算法并加入去重逻辑来解决在旋转且含有重复元素的数组中搜索特定值的问题。
LeetCode第81题搜索旋转排序数组 II
|
12月前
【LeetCode 39】700.二叉搜索树中的搜索
【LeetCode 39】700.二叉搜索树中的搜索
76 0
|
12月前
|
算法 C++
Leetcode第59题(螺旋矩阵2)
这篇文章介绍了解决LeetCode第59题“螺旋矩阵II”的算法,通过C++编程实现按顺时针顺序填充一个n x n的正方形矩阵。
71 0
|
算法 Java
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
150 6
LeetCode第74题搜索二维矩阵
文章讲解了LeetCode第74题"搜索二维矩阵"的解决方案,利用二分搜索法将问题简化,并通过数学转换找到二维矩阵中的对应元素,展示了将二维问题转化为一维问题的解题技巧。
LeetCode第74题搜索二维矩阵
LeetCode第35题搜索插入位置
这篇文章介绍了LeetCode第35题"搜索插入位置"的解题方法,通过使用二分查找法,高效地找到在有序数组中插入一个目标数的最佳位置。
LeetCode第35题搜索插入位置