【LeetCode240.搜索二维矩阵Ⅱ】以及变式

题目链接

240. 搜索二维矩阵 II - 力扣(LeetCode)

实现思路

  • 利用行有序、列有序的特点,可以从右上角或者左下角开始判断,以左下角为例,如果小于目标值就向右移动,也就排除了一列;如果大于目标值就向上移动,也就排除了一行。时间复杂度为O(m+n)。
    • 为什么不从左上角或者右下角判断呢,以右下角为例,如果小于目标值,这个矩阵的最大值小于目标值,说明肯定就找不到目标值,如果大于目标值,可以向左也可以向上,移动的方向不唯一。
  • (之前想的是每次遍历一行,然后二分找,但是这样时间复杂度是O(mlogn))。

代码实现

cpp 复制代码
class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) { 
        int m = matrix.size();
        int n = matrix[0].size();
        int i = m - 1, j = 0;
        while (true) {
            if (matrix[i][j] > target) {
                i--;
            } else if (matrix[i][j] < target) {
                j++;
            } else {
                return true;
            }
            if (i == -1 || j == n) {
                return false;
            }
        }
        return false;
    }
};

变式

  • 如果存在重复元素,找最小下标呢?这里所说的最小下标指的是行优先,也就是i越小认为下标越小。
cpp 复制代码
class Solution {
public:
    vector<int> searchMatrix(vector<vector<int>>& matrix, int target) {
        int m = matrix.size();
        int n = matrix[0].size();
        int i = 0, j = n - 1;
        while (true) {
            if (matrix[i][j] > target) {
                j--;
            } else if (matrix[i][j] < target) {
                i++;
            } else {
                int left = target + 1;
                if (j - 1 >= 0) {
                    left = matrix[i][j - 1];
                }
                if (left == target) {
                    j--;
                } else {
                    return {i, j};
                }
            }
            if (i == m || j == -1) {
                break;
            }
        }
        return {-1, -1};
    }
};