前言
最近在刷牛客的剑指offer,刷的过程中会遇到各种各样的算法,用此系列贴记录下来。
题目描述
在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[
[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]
]
给定 target = 7,返回 true。
给定 target = 3,返回 false。
0 <= array.length <= 500
0 <= array[0].length <= 500
我最初的方法是每行二分法查找
代码如下
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
for (int i = 0; i < array.size(); i++) {
if (HalfFind(target, array[i]))
return true;
}
return false;
}
bool HalfFind(int target, vector<int> a) {
int begin = 0;
int fin = a.size() - 1;
while (begin <= fin) {
int m = (fin + begin) / 2;
if (a[m] == target)
return true;
else if (a[m] > target) {
fin = m - 1;
}
else {
begin = m + 1;
}
}
return false;
}
};
时间复杂度O(mlogn),空间复杂度O(1)
这种方法只用了每行为有序数列的特性,每列是有序数列的特性没用上,时间复杂度自然不是最佳。
++++++++++++++++++++++++++++++++++分界线+++++++++++++++++++++++++++++++++++
杨氏矩阵
先从矩阵的左下角(或右上角)开始,如果target比目前的值小,那么向上(向左)移动,target比目前的值大,那么向下(向右)移动,直到不能移动(即超出矩阵范围)为止。
(图片来自牛客网id:蒙牛麦片)
代码如下:
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
int m = array.size();
int n = array[0].size();
int i=m-1;
int j = 0;
while(i>=0&&j<n){
if(target==array[i][j])
return true;
else if(target<array[i][j])
i--;
else
j++;
}
return false;
}
};
时间复杂度O(m+n),空间复杂度O(1)
使用这种方法的条件是这个矩阵为杨氏矩阵,同理多维矩阵依旧可以类比这种方式。