力扣刷题笔记 → 240. 搜索二维矩阵 II

492 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

题目

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

  • 每行的元素从左到右升序排列。
  • 每列的元素从上到下升序排列。

示例

image.png

输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
输出:true

image.png

输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 20
输出:false

提示

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= n, m <= 300
  • -109^9 <= matrix[i][j] <= 109^9
  • 每行的所有元素从左到右升序排列
  • 每列的所有元素从上到下升序排列
  • -109^9 <= target <= 109^9

解题思路

暴力法

对于矩阵查找目标值,最简单的实现就是两层遍历即可找到所需的结果。

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int top = 0, bottom = matrix.length, left = 0, right = matrix[0].length;

        for(int i = top; i < bottom; ++i){
            for(int j = left; j < right; ++j){
                if(matrix[i][j] == target){
                    return true;
                }
            }
        }

        return false;
    }
}

复杂度分析

  • 时间复杂度:O(NM)O(NM)
  • 空间复杂度:O(1)O(1)

二分法

然而提示中还给我们提供多了两条信息:

  • 每行的所有元素从左到右升序排列
  • 每列的所有元素从上到下升序排列

对于有序的排列,我们就可以选择 二分法 来缩短排查的时间。

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int top = 0, bottom = matrix.length;

        for(int i = top; i < bottom; ++i){
            int left = 0, right = matrix[0].length;
            while(left < right){
                int mid = left + (right - left) / 2;
                if(matrix[i][mid] == target){
                    return true;
                }else if(matrix[i][mid] < target){
                    left = mid + 1;
                }else{
                    right = mid;
                }
            }
        }

        return false;
    }
}

复杂度分析

  • 时间复杂度:O(NlogN)O(NlogN)
  • 空间复杂度:O(1)O(1)

二分优化

对于上面的二分查找来说,不管是按行还是按列来排查,都需要一排排的逐行/列排查,对于有序的矩阵来说,当前位置坐标点(x, y)的值一定是比(x - 1, y), (x, y - 1)的值大,那么我们可以利用该特性来缩小排查范围,呈扇形范围扫描区间元素是否符合。

GIF 2021-10-26 16-03-08.gif

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int top = 0, bottom = matrix.length - 1, left = 0, right = matrix[0].length - 1;

        while(top <= bottom && left <= right){
            if(matrix[bottom][left] == target){
                return true;
            }else if(matrix[bottom][left] > target){
                --bottom;
            }else{
                ++left;
            }
        }

        return false;
    }
}

复杂度分析

  • 时间复杂度:O(N+M)O(N + M)
  • 空间复杂度:O(1)O(1)

最后

文章有写的不好的地方,请大佬们不吝赐教,错误是最能让人成长的,愿我与大佬间的距离逐渐缩短!

如果觉得文章对你有帮助,请 点赞、收藏、关注、评论 一键四连支持,你的支持就是我创作最大的动力!!!

题目出处: leetcode-cn.com/problems/se…