思路:

题目中给的信息:

  • 行和列都是有序的,且元素互异
  • 寻找的是目标值的坐标,从零开始

即这是一个二维矩阵上的查找,查找算法如下:

方法一:暴力搜索 直接两个for循环找到目标值的坐标

class Solution {
public:
    vector<int> findElement(vector<vector<int> > mat, int n, int m, int x) {
        vector<int> res;
        if(n == 0)  //先判断特殊
            return res; 
        for(int i = 0; i < n; i++){  //两层for循环,找到即可
            for(int j = 0; j < m; j++){
                if(mat[i][j] == x){  
                    res.push_back(i);
                    res.push_back(j);
                }    
            }
        }
        return res;
    }
};

复杂度分析:

  • 时间复杂度:O(nm),遍历矩阵
  • 空间复杂度:O(1)

方法二:二分搜索 既然矩阵里面的元素是有序且无重复的,我们可以好好利用一下。 首先看四个角,左上与右下必定为最小值与最大值,而左下与右上就有规律了: 左下元素大于它上方的元素,小于它右方的元素,右上元素与之相反。 我们可以在查找时使用二分法: 首先以左下角为起点,若是它小于目标元素,则往右移动去找大的,若是他大于目标元素,则往上移动去找小的。 图片说明

class Solution {
public:
    vector<int> findElement(vector<vector<int> > mat, int n, int m, int x) {
        vector<int> res;
        if(n == 0)
            return res; 
        for(int i = n - 1, j = 0; i >= 0 && j < m; ){ //从最左下角的元素开始往左或往上
            if(mat[i][j] > x){   //元素较大,往上走
                i--;
            }
            else if(mat[i][j] < x){ //元素较小,往右走
                j++;
            }
            else{
                res.push_back(i);
                res.push_back(j);
                break;
            }
        }
        return res;
    }
};

复杂度分析:

  • 时间复杂度:O(n+m),最多走过矩阵两个边长
  • 空间复杂度:O(1),未使用额外空间