搜索二维矩阵II

继续每日一题,今天给大家带来的是矩阵类型的题目

题目描述:

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

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

题目示例:

对于所有矩阵类型的题目,基本都是从一个点开始,上下左右四个方向移动,来完成整个矩阵的遍历

本题较为特殊:是行列数值是有序的,像这种有序的矩阵,我们一般需要观察一下四个角,来判断从哪一个角开始,常见的方法是从右上角或左下角开始。

以右上角为例(row=0, col=cols-1):

  • 如果当前元素等于target,返回true。
  • 如果当前元素大于target,因为当前元素是该列最小的(从该列往下递增),那么当前元素所在列的下方都会比当前元素大,所以我们可以将搜索范围向左移动一列(col--)。
  • 如果当前元素小于target,因为当前元素是该行最大的(从该行往左递减),那么当前元素所在行的左边都会比当前元素小,所以我们可以将搜索范围向下移动一行(row++)。
  • 直到找到target或者搜索完整个矩阵(row超出最后一行或者col小于0)。

这个方法的时间复杂度是O(m+n),因为每次移动一行或一列。

以case1的矩阵为例,假如我们要找的值是:23

我们从右上角开始:

  • row=0,col=4,对应元素=15<23,向下移动行
  • row=1,col=4,对应元素=19<23,向下移动行
  • row=2,col=4,对应元素=22<23,向下移动行
  • row=3,col=4,对应元素=24>23,此时找到了对应的行,开始向左移动列
  • row=3,col=3,对应元素=16<23,此时也找到了对应的列,继续向下移动行
  • row=4,col=3,对应元素=17<23,向下移动行
  • row=5,col=3,对应元素=26>23,此时找到了对应的行,开始向左移动列
  • row=5,col=2,对应元素=23=23,找到了对应的元素

所以整个过程就是:向下移动行直到找到对应的行,在向左移动列,然后重复该过程

核心代码如下:

java 复制代码
        int row = 0, col = cols - 1;
        while (row < rows && col >= 0) {
            while (row < rows) {
                //向下移动行
                int val = matrix[row][col];
                if (val == target) {
                    return true;
                } else if (val < target) {
                    row++;
                } else {
                    break;
                }
            }
            //所有元素均要比当前元素小
            if (row >= rows) {
                return false;
            }
            //向左移动列
            while (col >= 0) {
                int val = matrix[row][col];
                if (val == target) {
                    return true;
                } else if (val > target) {
                    col--;
                } else {
                    break;
                }
            }
        }

完整实现:

java 复制代码
    public static boolean searchMatrix(int[][] matrix, int target) {
        int rows = matrix.length;
        int cols = matrix[0].length;

        //先确定从哪一行开始找
        int row = 0, col = cols - 1;
        while (row < rows && col >= 0) {
            while (row < rows) {
                int val = matrix[row][col];
                if (val == target) {
                    return true;
                } else if (val < target) {
                    row++;
                } else {
                    break;
                }
            }
            //所有元素均要比当前元素小
            if (row >= rows) {
                return false;
            }
            //移动列
            while (col >= 0) {
                int val = matrix[row][col];
                if (val == target) {
                    return true;
                } else if (val > target) {
                    col--;
                } else {
                    break;
                }
            }
        }
        return false;
    }

耗时:

但是针对每一行或者每一列均是有序的,可以看到我们上面的过程是每次均只在固定的行和固定的列在移动,所以每次在确定行或者列的时候我们可以利用二分法来提高检索速度

java 复制代码
   public static boolean searchMatrix2(int[][] matrix, int target) {
        int rows = matrix.length;
        int cols = matrix[0].length;

        //先确定从哪一行开始找
        int row = 0, col = cols - 1;
        while (row < rows && col >= 0) {
            int top = row, bottom = rows - 1;
            while (top <= bottom) {
                int mid = (top + bottom) / 2;
                int val = matrix[mid][col];
                if (val == target) {
                    return true;
                } else if (val < target) {
                    top = mid + 1;
                } else {
                    bottom = mid - 1;
                }
            }
            row = top;
            //所有元素均要比当前元素小
            if (row >= rows) {
                return false;
            }
            //移动列
            int left = 0, right = col - 1;
            while (left <= right) {
                int mid = (left + right) / 2;
                int val = matrix[row][mid];
                if (val == target) {
                    return true;
                } else if (val < target) {
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            }
            col = right;
        }
        return false;
    }
相关推荐
AI科技星12 小时前
特征值与特征向量不是矩阵特殊解,是变换矩阵下不改变生长方向、仅缩放体量的固有主螺旋脉络 -《全域数学vs传统数学:人类文明进阶200讲》第73讲
人工智能·线性代数·矩阵·数据挖掘·回归·乖乖数学·全域数学
学究天人14 小时前
数学公理体系大全:Comprehensive Collection of Mathematical Axiom Systems(卷7)
线性代数·矩阵·动态规划·概率论·图论·抽象代数·拓扑学
USB_ABC18 小时前
视频矩阵核心技术对比:模块化vs固定机箱、硬件帧同步vs软件同步怎么选
矩阵·音视频
workflower1 天前
室内外配送机器人-应用路径
人工智能·机器学习·设计模式·矩阵·自动化
lin9902122 天前
内容矩阵批量分发实战
大数据·人工智能·矩阵
C137的本贾尼2 天前
第8章:把向量组织起来——矩阵与线性变换
线性代数·矩阵
hai3152475433 天前
九章芯片电路集成体系:密度矩阵逆向·全域均衡网络计算总框架
网络·线性代数·矩阵
木木子223 天前
# 星座配对深度解析:Select 长列表选择器、矩阵评分算法与数据驱动建议
java·算法·华为·矩阵·harmonyos
最爱老式锅包肉5 天前
《HarmonyOS技术精讲-ArkGraphics 2D(方舟2D图形服务)》第四篇:变换的魔术——平移、旋转、缩放与矩阵变换
华为·矩阵·harmonyos
phoenix@Capricornus5 天前
单位球面在线性变换下的像以及线性变换诱导的加权 2-范数的等值面(To 战老师)
线性代数·机器学习·矩阵