0
点赞
收藏
分享

微信扫一扫

[查找]BM18 二维数组中的查找-中等

​​BM18 二维数组中的查找​​


知识点​​数组​​

描述

在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。[[1,2,8,9],

[2,4,9,12],

[4,7,10,13],

[6,8,11,15]

]

给定 target = 7,返回 true。

给定 target = 3,返回 false。

数据范围:矩阵的长宽满足 [查找]BM18 二维数组中的查找-中等_二维数组 , 矩阵中的值满足 [查找]BM18 二维数组中的查找-中等_二分查找_02

进阶:空间复杂度 [查找]BM18 二维数组中的查找-中等_二维数组_03 ,时间复杂度 [查找]BM18 二维数组中的查找-中等_二分查找_04

示例1

输入:

7,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]

复制返回值:

true

复制说明:

存在7,返回true

示例2

输入:

1,[[2]]

复制返回值:

false

复制

示例3

输入:

3,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]

复制返回值:

false

复制说明:

不存在3,返回false

题解

思路:

根据前面的​​[查找]BM17 二分查找-I-简单 ​​实现,我们可以很容易的想到对二维数组进行遍历,然后在一维上使用二分查找实现。但是题目要求最佳的时间复杂度为O(M+N),该如何实现呢?

其实解法也和一维数组的二分查找类似,我们先定义一个结构体point来表示坐标。按照一维数组的二分查找我们可以进行以下推导:

  • 一维数组我们是先获取了起始、结尾坐标,同样的二维数组我们也先获取起始、结尾坐标
  • 一维数组二分的时候是先查找中间节点,比较中间节点和目标值的大小,然后根据大小选取左右区间,同样的,我们先获取二维数组的中间节点,然后根据大小选取左右节点进行查找。根据二维数组的有序特点,我们可以使用中间节点根据大小将数组划分成2个区间,然后再在我们需要的区间中进行查找。

注意:

一定要注意数组边界的选取,如果没有使用数组边界进行判断,那么可能导致递归~~~

代码如下:

#include <bits/stdc++.h>

using namespace std;

// 定义的坐标
// x:横坐标
// y:纵坐标
struct point
{
int x;
int y;
point()
{
x = 0;
y = 0;
}
point(int x, int y) : x(x), y(y) {}
};

// 一维数组的二分查找,成功返回下标,失败返回-1
int binary_search(const std::vector<int> &nums, int left, int right, int target)
{
while (left <= right)
{
int mid = (left + right) / 2;
if (nums[mid] == target)
{
return mid;
}

if (nums[mid] < target)
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
return -1;
}

// 对二维数组的二分查找实现
// array:二维数组
// left:坐标下限
// right:坐标上限
// target:目标值
bool search_array(const vector<vector<int>> &array, const point &left, const point &right, int target)
{
if (left.y > right.y || left.x > right.x)
{
return false;
}
if (left.y == right.y)
{
return binary_search(array[left.y], left.x, right.x, target) != -1;
}
int max_x = right.x;
int max_y = right.y;
int min_x = left.x;
int min_y = left.y;
point mid((left.x + right.x) / 2, (left.y + right.y) / 2);
int value = array[mid.y][mid.x];
if (value == target)
{
return true;
}
if (value < target)
{
if ((mid.x + 1 <= max_x) && search_array(array, point(mid.x + 1, left.y), point(max_x, mid.y), target))
{
return true;
}

if ((mid.y + 1 <= max_y) && search_array(array, point(left.x, mid.y + 1), right, target))
{
return true;
}
return false;
}

if (mid.x > min_x && search_array(array, point(left.x, mid.y), point(mid.x - 1, right.y), target))
{
return true;
}

if ((mid.y > min_y) && search_array(array, left, point(max_x, mid.y - 1), target))
{
return true;
}
return false;
}

bool Find(int target, vector<vector<int>> array)
{
if (array.empty() || (array.size() == 1 && array[0].size() == 0))
{
return false;
}

point left(0, 0);
point right(array[0].size() - 1, array.size() - 1);
return search_array(array, left, right, target);
}

int main()
{
// std::vector<std::vector<int>> nums = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
std::vector<std::vector<int>> nums = {{1, 2, 8, 9}, {4, 7, 10, 13}};
int target = 7;
std::cout << (Find(target, nums) ? "true" : "false") << std::endl;
return 0;
}
举报

相关推荐

0 条评论