Leetcode算法学习日志 -240 Search a 2D Matrix 2

来源:互联网 发布:压缩弹簧计算软件 编辑:程序博客网 时间:2024/06/07 19:45

Leetcode 240 Search a 2D Matrix 2

题目原文

Write an efficient algorithm that searches for a value in anm x n matrix. This matrix has the following properties:

  • Integers in each row are sorted in ascending from left to right.
  • Integers in each column are sorted in ascending from top to bottom.

For example,

Consider the following 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]]

Given target = 5, returntrue.

Given target = 20, returnfalse.

题意分析

这道题需要在一个二维容器里搜索一个元素是否存在,如果采用brute force,则复杂度为O(mn),为了减小复杂度,需要充分利用行列都是递增的特点。

解法分析

本题采用了两种方法来解:

  • 分治递归
  • 充分利用递增特点

分治递归

这道题很自然可以想到可以将大矩阵分成多个小矩阵来进行搜索。对于行和列下标均在中心的元素m,如果target等于它,直接返回ture,如果target大于它,则target一定不存在于左上的子矩阵,所以可以对右上、右下、左下的子矩阵递归调用查找函数,注意这几个子矩阵都不能将m包含进去,否则在在极端情况([5,2] 1)时,会无限调用r为m,l也为m的查找函数,递归的返回条件一般比较统一,如果需要判断的条件太多,说明还未找到各种情况的共同点,需要进一步分析。C++代码如下:

class Solution {private: int target;public:    bool searchMatrix(vector<vector<int>>& matrix, int Target) {        target=Target;        if(matrix.size()==0||matrix[0].size()==0)            return false;        pair<int,int> l=make_pair(0,0);        pair<int,int> r=make_pair(matrix.size()-1,matrix[0].size()-1);        return searchM(matrix,l,r);      }public:    bool searchM(vector<vector<int>>&matrix,pair<int,int> l,pair<int,int> r){        if(l.first>r.first||l.second>r.second)//这是找到的各种情况下的返回条件            return false;        pair<int,int> m=make_pair((l.first+r.first)/2,(l.second+r.second)/2);        if(matrix[m.first][m.second]==target)            return true;            else if(matrix[m.first][m.second]>target){            return      (searchM(matrix,l,make_pair(m.first-1,m.second-1))||searchM(matrix,make_pair(l.first,m.second),make_pair(m.first-1,r.second))||searchM(matrix,make_pair(m.first,l.second),make_pair(r.first,m.second-1)));        }        else{            return (searchM(matrix,make_pair(m.first+1,m.second+1),r)||searchM(matrix,make_pair(l.first,m.second+1),make_pair(m.first,r.second))||searchM(matrix,make_pair(m.first+1,l.second),make_pair(r.first,m.second)));                    }       }};
在这种查找题目中,一定要检查被查找矩阵是否为空。如运行后错误提示为runtime error,一般是内存访问错误或者栈溢出,timeout是提交网络问题,time limit exceeded是算法时间太长。上述算法的递归式为T(mn)=3T(mn/4)+O(1),略微小于O(mn)。

充分利用递增特点

由于每行都是递增的,说明每行最后一个元素是该行最大的,如果target小于这个元素,则从右到左查找这一行,如果找到相同元素,则返回true,如果将这一行遍历完都没有找到,返回false,如果发现target大于某个元素了,则换到下一行的统一列元素,继续按这种方法比较。C++代码如下:

class Solution {public:    bool searchMatrix(vector<vector<int>>& matrix, int target) {        int m=matrix.size();        if(m==0)            return false;        int n=matrix[0].size();        int i=0,j=n-1;        while(i<m&&j>=0){            if(matrix[i][j]==target)                return true;            else if(matrix[i][j]>target)                j--;            else                i++;        }        return false;      }};
最坏情况下,算法会从第一行一直切换到最后一行,算法复杂度为O(m+n),远小于O(mn)。

原创粉丝点击