剑指 Offer 04. 二维数组中的查找(C++) 修剪路线

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

示例:

现有矩阵 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。
给定 target = 20,返回 false。

限制:

0 <= n <= 1000
0 <= m <= 1000

注意:本题与主站 240 题相同:https://leetcode-cn.com/problems/search-a-2d-matrix-ii/

算法:

首先,我们初始化一个指向矩阵左下角的 (row,col) 指针。然后,直到找到目标并返回 true(或者指针指向矩阵维度之外的 (row,col) 为止,我们执行以下操作:如果当前指向的值大于目标值,则可以 “向上” 移动一行。 否则,如果当前指向的值小于目标值,则可以移动一列。不难理解为什么这样做永远不会删减正确的答案;因为行是从左到右排序的,所以我们知道当前值右侧的每个值都较大。 因此,如果当前值已经大于目标值,我们知道它右边的每个值会比较大。也可以对列进行非常类似的论证,因此这种搜索方式将始终在矩阵中找到目标(如果存在)。

先放C++代码(最优解),思路清晰明了,面试官直呼内行。本题与剑指offer第4题一样,详细题解也可以移步剑4: 二维数组中的查找。(字节题库)
————————————————
版权声明:本文为CSDN博主「伍粟」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_30457077/article/details/114192468

class Solution {
    
    
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
    
    
        if(matrix.empty() || matrix[0].empty()) return false;
        //获取行列尺寸
        int rowSize = matrix.size(), columnSize = matrix[0].size();
        int row = 0, column = columnSize - 1;
        while(row < rowSize && column >= 0)
        {
    
    
            // 从矩阵的右上角开始匹配,如果匹配到了,返回true
            if(matrix[row][column] == target) return true;
            // 如果值比target小,则说明这一行都比target小,row往下移一行
            else if(matrix[row][column] < target) row ++;
            // 如果值比target大,说明这一列都比target大,column往左移一行
            else column --;
        }
        return false;
    }
};

复杂度分析

时间复杂度:O(n+m)。
时间复杂度分析的关键是注意到在每次迭代(我们不返回 true)时,行或列都会精确地递减/递增一次。由于行只能减少 m 次,而列只能增加 n 次,因此在导致 while 循环终止之前,循环不能运行超过 n+m 次。因为所有其他的工作都是常数,所以总的时间复杂度在矩阵维数之和中是线性的。
空间复杂度:O(1),因为这种方法只处理几个指针,所以它的内存占用是恒定的。

猜你喜欢

转载自blog.csdn.net/qq_30457077/article/details/114676997