Day16 2023/01/23
难度:简单
题目
在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[
[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]
]
给定 target = 7,返回 true。
给定 target = 3,返回 false。
数据范围:矩阵的长宽满足 0 ≤ n , m ≤ 500 , 矩阵中的值满足 0 ≤ val ≤
进阶:空间复杂度:O(1) ,时间复杂度: O(n+m)
示例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
思路
本题的进阶要求了时间复杂度: O(n+m),所以不能使用暴力解法,但是题目中要求的:每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序,所以可以使用 二分查找,时间复杂度也正好合适。大致的解题过程:逐行使用二分查找, 查找是否含有target
关键点
- 对于二分查找不熟悉的朋友可以看这个:点击链接
算法实现
c++代码实现-二分查找
#include <iostream>
#include <vector>
using namespace std;
//按照题目要求输入数组数据
vector<vector<int>> createArray() {
cout << "输入数组长宽,并输入数据:" << endl;
int wh, val;
cin >> wh; //二维数组长宽
vector<vector<int>> arr(wh, vector<int> (wh)); //创建一个长宽wh的二维数组
for (int i = 0; i < wh; i++) { //外层控制行,内层控制列
for (int j = 0; j < wh; j++) {
cin >> val;
arr[i][j] = val; //赋值
}
}
return arr; //返回二维数组
}
//二分查找目标元素(这里合法区间采用左闭右闭)
bool binarySearch(vector<int> arr, int target) {
int left = 0, right = arr.size() - 1;
while (left <= right) {
int mid = left + ((right - left) >> 2);
if (target > arr[mid]) left = mid + 1; //更新查找区间
else if (target < arr[mid]) right = mid - 1;
else return true; //成功找到返回
}
return false;
}
int main() {
vector<vector<int>> arr = createArray(); //创建二维数组
cout << "输入查找值:";
int target; //查找值
cin >> target;
for (auto it : arr) { //it是复制的一份,无法影响真正的arr
if(binarySearch(it, target)) cout << "成功找到";
}
return 0;
}
- 时间复杂度 --- n为数组长度(一次二分查找循环n次),m为数组宽度(共调用m次二分查找)
- 空间复杂度 ---数组为必要空间,无额外辅助空间
总结
- 根据对复杂度要求的不同,解题方法也会有所限制。