题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[
[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]
]
给定 target = 7,返回 true。
给定 target = 3,返回 false。
思路
示例1
输入:7,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
返回值:true
说明:存在7,返回true
示例2
输入:3,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
返回值:false
说明:不存在3,返回false
- 遍历每一行,每行按照二分查找。假设
m
m
m行,
n
n
n列
时间复杂度: O ( m l o g n ) O(mlogn) O(mlogn)
空间复杂度: O ( 1 ) O(1) O(1)
class Solution {
public:
bool Find(int target, vector<vector<int> > array)
{
//计算得到行列长度
int Mid;
// 从行的中间,进行二分法
for(int i = 0; i < array.size(); ++i)
{
int L = 0;
int R = array[0].size() - 1;
while(L <= R)
{
Mid = L + ((R-L)>>1);
if(target == array[i][Mid])
return true;
else if(target > array[i][Mid])
L = Mid + 1;
else
R = Mid - 1;
}
}
return false;
}
};
- 利用这个二维数组的规律(从上到下)(从左到右)都是递增。可以选择从左下角或者右上角开始查找。(此处选择左下角)
假若 t a r g e t target target 比 左下角的值大:就在往右查找确定 t a r g e t target target 可能存在的列数—— 当右侧某值小于 t a r g e t target target 时,必然不在此值所在的列(从上到下都是递增,上方的必然小于 t a r g e t target target ),若全都小于 t a r g e t target target 时, t a r g e t target target 不在二维数组中;只有当右侧某值大于 t a r g e t target target 时,才可能在此值列中,因此需要向上查找。
总的来说是向上向右的查找(要么向右要么向左)。要么按行递减要么按列递增不断的逼近 t a r g e t target target 。
最差情况是从左下角走到右上角(反之一样),行走m,列走n
时间复杂度为:
O
(
m
+
n
)
O(m+n)
O(m+n)
内存复杂度为:
O
(
1
)
O(1)
O(1)
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
// 判断是否为空
if(array.empty() || array[0].empty())
return false;
int i = array.size() - 1, j = 0;
while(i >= 0 && i < array[0].size())
{
if(target == array[i][j])
return true;
else if(target > array[i][j])
++j;
else
--i;
}
return false;
}
};