m
*n
的二维数组 plants
记录了园林景观的植物排布情况,具有以下特性:
- 每行中,每棵植物的右侧相邻植物不矮于该植物;
- 每列中,每棵植物的下侧相邻植物不矮于该植物。
请判断 plants
中是否存在目标高度值 target
。
示例 1:
输入:plants = [[2,3,6,8],[4,5,8,9],[5,9,10,12]], target = 8 输出:true
示例 2:
输入:plants = [[1,3,5],[2,5,7]], target = 4 输出:false
提示:
0 <= n <= 1000
0 <= m <= 1000
注意:本题与主站 240 题相同:. - 力扣(LeetCode)
题解:
直接搜索:
考虑到是一个行递增,列递增的数组,所以如果依次搜索的话,小于等于target的应该位于左上角。遇到大于的就到下一行。O(n^2)
bool findTargetIn2DPlants(int** plants, int plantsSize, int* plantsColSize, int target) {
for(int i=0;i<plantsSize;i++){
for(int j=0;j<*plantsColSize;j++){
if(plants[i][j]>target)
{break;}
if(plants[i][j]==target)
return true;
}
}
return false;
}
二分查找
因为行列之间都是有序的,可以考虑二分查找。
bool binarySearch(int* arr,int size,int target){
int mid,low=0,high=size-1;
while(low<=high){
mid=(low+high)/2;
if(arr[mid]<target)
low=mid+1;
else if(arr[mid]>target)
high=mid-1;
else
return true;
}
return false;
}
bool findTargetIn2DPlants(int** plants, int plantsSize, int* plantsColSize, int target) {
for(int i = 0; i < plantsSize; i++){
if(binarySearch(plants[i], *plantsColSize, target))
return true;
}
return false;
}
但是二分查找在此处只能优化一行或者一列。
我们要利用整个矩阵的特点。
因为行递增,列也递增。我们可以找一个中间标记值,进行移动。
选取最上面一行最右边一列的,是该行的最大值。且从该位置往下都是增大。
如果target先和它比,比它小就左移,比它大就下移,这样可以有一定程度的优化。
矩阵搜索
bool findTargetIn2DPlants(int** plants, int plantsSize, int* plantsColSize, int target) {
//判断是否数组是否为空
if (plants == NULL||plantsSize == 0 || *plantsColSize == 0) {
return false;
}
int i=0,j=*plantsColSize-1;
while(i<plantsSize&&j>=0){
if(target<plants[i][j]){
j--;
}
else if(target>plants[i][j]){
i++;
}
else
return true;
}
return false;
}