LeetCode/二维矩阵搜索

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

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

1. 暴力求解

两重循环,时间复杂度O(m*n)

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        for (const auto& row: matrix) 
            for (int element: row) 
                if (element == target) 
                    return true;
        return false;
    }
};

2. Z字形双指针/起始点(0,n-1)

由于二维数组在行列上分别满足升序,可以用两个指针分别找出其在行与列上的位置
行从前往后遍历,列从后往前遍历,之所以不能同时一个方向,是与target比较时,无法决定先移动哪个指针
时间复杂度为O(m+n)

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int m = matrix.size(), n = matrix[0].size();
        int x = 0, y = n - 1;
        while (x < m && y >= 0) {
            if (matrix[x][y] == target) 
                return true;
            else (matrix[x][y] > target) 
                --y;
            else ++x;
        }
        return false;
    }
};

3. 回溯法(深度优先)

递归向右和向下,对于遍历过的路径做标记防止重复
时间复杂度应该为O(m*n),但不知道为什么实际执行时性能比方法二还好

回溯法
class Solution {
public:
    bool flag=false;
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        search(matrix,target,0,0);
        return flag;
    }

    void search(vector<vector<int>>& matrix,int target,int i,int j){
        if(flag==true||matrix[i][j]==-2) return; //剪去其他遍历分支

        if(matrix[i][j]==target){ flag=true; return;}//满足条件跳出遍历
        if(matrix[i][j]<target) {
            matrix[i][j]=-2;//做标记
            if(i<matrix.size()-1)
                search(matrix,target,i+1,j);//向下递归
            if(j<matrix[0].size()-1)   
                search(matrix,target,i,j+1);//向右递归
        }
        else matrix[i][j]=-2;//做标记
    }
};
posted @ 2022-05-14 14:22  失控D大白兔  阅读(38)  评论(0编辑  收藏  举报