【LeetCode从零单刷】Search a 2D Matrix I & II
2015-10-30 11:10
519 查看
I 题目:
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
Integers in each row are sorted from left to right.
The first integer of each row is greater than the last integer of the previous row.
For example,
Consider the following matrix:
Given target =
解答:
因为排序过,思路很清晰。建立每行首元素的索引,然后行二分搜索,最后列二分搜索。复杂度是O(lg(m) + lg(n))。但是难点在于细节:
这里的搜索可能 False,也就是找不到元素。因此,如果 first = 1,last = 2,mid = (first + last)/2 = 1。下一次如果 first = mid = 1,又陷入了循环;
因为除法取整的原因,有可能 last 一直无法取到。如果 first = 1,last = 2,mid = (first + last)/2 = 1。下一次如果 first = mid = 1,还是取不到 last = 2 的值。因此需要多判断一次 last 的值;
关于每行首元素的索引中的搜索,不同于列搜索。即使 target > 索引中的最大值,还是有可能存在此元素。例如 target = 30 > 23,依然存在
当然,二分搜索还有一种实现方法,就是每次必然移动一位。例如:head = mid +1,tail = mid- 1。
只是这样实现,需要在循环中单独预先判断 head,tail,mid 处的值。具体实现可参见:《Search in Rotated Sorted Array I & II》
II 题目:
Write an efficient algorithm that searches for a value in an m x
n matrix. This matrix has the following properties:
Integers in each row are sorted in ascending from left to right.
Integers in each column are sorted in ascending from top to bottom.
For example,
Consider the following matrix:
Given target =
Given target =
解答:
我的做法比较简单,对每行的首尾遍历范围,行内二分搜索。算法复杂度为 O(m * log n):
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if (matrix.empty() || matrix[0].empty()) return false;
int m = matrix.size();
int n = matrix[0].size();
int left, right, mid;
for (int i = 0; i<m; i++) {
if (matrix[i][0] <= target && target <= matrix[i][n - 1]) {
left = 0;
right = n - 1;
while(left <= right) {
mid = (left + right) / 2;
if (matrix[i][left] == target || matrix[i][right] == target || matrix[i][mid] == target)
return true;
if (matrix[i][mid] > target) right = mid - 1;
if (matrix[i][mid] < target) left = mid + 1;
}
}
}
return false;
}
};但其实还有一种 O(n ^ 1.58) 的复杂度:分治法。
以矩形中点为基准,将矩阵拆分成左上,左下,右上,右下四个区域。若中点值 < 目标值,则舍弃左上区域,从其余三个区域再行查找若中点值 > 目标值,则舍弃右下区域,从其余三个区域再行查找。
具体算法实现与复杂度推导(利用 “主定理 master theorem” 计算复杂度)见:传送门
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
Integers in each row are sorted from left to right.
The first integer of each row is greater than the last integer of the previous row.
For example,
Consider the following matrix:
[ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ]
Given target =
3, return
true.
解答:
因为排序过,思路很清晰。建立每行首元素的索引,然后行二分搜索,最后列二分搜索。复杂度是O(lg(m) + lg(n))。但是难点在于细节:
这里的搜索可能 False,也就是找不到元素。因此,如果 first = 1,last = 2,mid = (first + last)/2 = 1。下一次如果 first = mid = 1,又陷入了循环;
因为除法取整的原因,有可能 last 一直无法取到。如果 first = 1,last = 2,mid = (first + last)/2 = 1。下一次如果 first = mid = 1,还是取不到 last = 2 的值。因此需要多判断一次 last 的值;
关于每行首元素的索引中的搜索,不同于列搜索。即使 target > 索引中的最大值,还是有可能存在此元素。例如 target = 30 > 23,依然存在
class Solution { public: bool searchMatrix(vector<vector<int>>& matrix, int target) { vector<int> rowfirst; for(int i=0; i<matrix.size(); i++) rowfirst.push_back(matrix[i][0]); int head = 0; int tail = matrix.size() - 1; while(head <= tail){ if(head + 1 == tail || head == tail){ if(target == rowfirst[head] || target == rowfirst[tail]) return true; else break; } int mid = (head + tail) / 2; if(target > rowfirst[tail]) head = tail; else if(target == rowfirst[mid] || target == rowfirst[tail]) return true; else if(target < rowfirst[mid]) tail = mid; else if(target > rowfirst[mid]) head = mid; } if(head > tail) return false; int first = 0; int last = matrix[0].size() - 1; while(first <= last){ if(first == last || first + 1 == last){ if (matrix[head][first] == target || matrix[head][last] == target) return true; else return false; } int mid = (first + last) / 2; if(target == matrix[head][mid] || target == matrix[head][last]) return true; else if(target < matrix[head][mid]) last = mid; else if(target > matrix[head][mid]) first = mid; } return false; } };
当然,二分搜索还有一种实现方法,就是每次必然移动一位。例如:head = mid +1,tail = mid- 1。
只是这样实现,需要在循环中单独预先判断 head,tail,mid 处的值。具体实现可参见:《Search in Rotated Sorted Array I & II》
II 题目:
Write an efficient algorithm that searches for a value in an m x
n matrix. This matrix has the following properties:
Integers in each row are sorted in ascending from left to right.
Integers in each column are sorted in ascending from top to bottom.
For example,
Consider the following matrix:
[ [1, 4, 7, 11, 15], [2, 5, 8, 12, 19], [3, 6, 9, 16, 22], [10, 13, 14, 17, 24], [18, 21, 23, 26, 30] ]
Given target =
5, return
true.
Given target =
20, return
false.
解答:
我的做法比较简单,对每行的首尾遍历范围,行内二分搜索。算法复杂度为 O(m * log n):
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if (matrix.empty() || matrix[0].empty()) return false;
int m = matrix.size();
int n = matrix[0].size();
int left, right, mid;
for (int i = 0; i<m; i++) {
if (matrix[i][0] <= target && target <= matrix[i][n - 1]) {
left = 0;
right = n - 1;
while(left <= right) {
mid = (left + right) / 2;
if (matrix[i][left] == target || matrix[i][right] == target || matrix[i][mid] == target)
return true;
if (matrix[i][mid] > target) right = mid - 1;
if (matrix[i][mid] < target) left = mid + 1;
}
}
}
return false;
}
};但其实还有一种 O(n ^ 1.58) 的复杂度:分治法。
以矩形中点为基准,将矩阵拆分成左上,左下,右上,右下四个区域。若中点值 < 目标值,则舍弃左上区域,从其余三个区域再行查找若中点值 > 目标值,则舍弃右下区域,从其余三个区域再行查找。
具体算法实现与复杂度推导(利用 “主定理 master theorem” 计算复杂度)见:传送门
相关文章推荐
- 十分钟搞清字符集和字符编码
- Java Socket编程
- Lua 元表
- C++中的关键字用法--- 四种强制类型转换的总结
- 微信JS SDK Demo 官方案例
- 岭回归和lasso回归的r语言代码
- hybird app开发框架 ionic +angularjs + ng-cordova
- ARCEngine exe不正常关闭
- Android应用重启
- swift 快速奔跑的兔几 本节的内容是:协议和委托
- 从xib加载UIViewController的一个坑
- 二叉树的遍历(递归、非递归)
- [转]IOS 贝塞尔曲线UIBezierPath方法总结
- 解决SpringMVC项目的乱码问题
- Using GPUImage to Recreate iOS 7 Glass Effect
- 一个简单的富文本编辑器
- LyncServer2013归档服务器部署之查看员工聊天记录
- SQLSERVER读取ORACLE缺少数据,OPENQUERY只能读取一条数据
- BarCode Reader SDK使用教程:如何解PDF147码
- HTTP 状态码