Leetcode 074 探索二维矩阵 Python C++ 史上最详细题解系列
2018-08-11 10:07
555 查看
每天更新一道python or C++ leetcode题,力求讲解清晰准确,客官们可以点赞或者关注。
题目:
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
- 每行中的整数从左到右按升序排列。
- 每行的第一个整数大于前一行的最后一个整数。
示例 1:
[code]输入: matrix = [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] target = 3 输出: true
示例 2:
[code]输入: matrix = [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] target = 13 输出: false
这道题明摆着让我们使用二分思路嘛。
但是在细节的处理上也有较多不同。
方法一:
这道题要求搜索一个二维矩阵,由于给的矩阵是有序的,所以很自然的想到要用二分查找法,我们可以在第一列上先用一次二分查找法找到目标值所在的行的位置,然后在该行上再用一次二分查找法来找是否存在目标值,代码如下:
C++:
[code]class Solution { public: bool searchMatrix(vector<vector<int> > &matrix, int target) { if (matrix.empty() || matrix[0].empty()) return false; if (target < matrix[0][0] || target > matrix.back().back()) return false; int left = 0, right = matrix.size() - 1; //先找目标数在哪一行 while (left <= right) { int mid = (left + right) / 2; if (matrix[mid][0] == target) return true; else if (matrix[mid][0] < target) left = mid + 1; else right = mid - 1; } //行数为right的值 int tmp = right; left = 0; right = matrix[tmp].size() - 1; //接下来就是在一行里实现二分查找了 while (left <= right) { int mid = (left + right) / 2; if (matrix[tmp][mid] == target) return true; else if (matrix[tmp][mid] < target) left = mid + 1; else right = mid - 1; } return false; } };
方法二:
利用matrix的特性(每一行的数字的数目相同),可以直接定位到所有数据的中间的数。实际上这就是把二维数组变成一个一维数组,这其中的坐标转换是逻辑关键点。
Python:
[code]class Solution: def searchMatrix(self, matrix, target): """ :type matrix: List[List[int]] :type target: int :rtype: bool """ m = len(matrix) if m == 0: return False n = len(matrix[0]) if n == 0: return False #l-r是矩阵包含的所有数字 l, r = 0, m * n - 1 while l <= r: #最中间的数字 mid = (l + r) // 2 #mid//n为最中间数字所在的行,mid%n为所在的列 if matrix[mid // n][mid % n] == target: return True elif matrix[mid // n][mid % n] < target: l = mid + 1 else: r = mid - 1 return False
C++
[code]// One binary search class Solution { public: bool searchMatrix(vector<vector<int> > &matrix, int target) { if (matrix.empty() || matrix[0].empty()) return false; if (target < matrix[0][0] || target > matrix.back().back()) return false; int m = matrix.size(), n = matrix[0].size(); int left = 0, right = m * n - 1; while (left <= right) { int mid = (left + right) / 2; if (matrix[mid / n][mid % n] == target) return true; else if (matrix[mid / n][mid % n] < target) left = mid + 1; else right = mid - 1; } return false; } };
总结:方法一中,tmp = right,是因为left不能确定正确的行数,因为left+1是因为matrix[mid][0] < target,但是target还是有可能在这一行的,所以只有right的值才代表target所在的行数。
阅读更多相关文章推荐
- Leetcode 80 删除排序数组中的重复项 II Python C++ 史上最详细题解系列
- Leetcode 077 组合 Python C++ 史上最详细题解系列
- Leetcode 075 颜色分类 Python C++ 史上最详细题解系列(多解法)
- Leetcode 81 搜索旋转排序数组 II Python C++ 史上最详细题解系列
- Leetcode 078 子集 Python C++ 史上最详细题解系列
- Leetcode 82 删除排序链表中的重复元素 II Python C++ 史上最详细题解系列
- Leetcode 076 最小覆盖子串 Python C++ 史上最详细题解系列
- Leetcode 079 搜索单词 Python C++ 史上最详细题解系列
- Leetcode 83 删除排序链表中的重复元素 Python C++ 史上最详细题解系列
- Leetcode 312 打气球 Burst Balloons C++ 史上最详细题解系列
- 【LeetCode-面试算法经典-Java实现】【074-Search a 2D Matrix(搜索二维矩阵)】
- leetcode_效率题解_[python/C++]_147. Insertion Sort List(链表插入排序)
- [LeetCode]题解(python):074-Search a 2D Matrix
- leetcode_效率题解_[python/C++]_21. Merge Two Sorted Lists(合并2个有序链表)
- [LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql)
- LeetCode题解汇总(C++ Java Python,含题目翻译)
- [LeetCode] Two Sum Python 题解
- Leetcode题解(Python): 17. Letter Combinations of a Phone Number
- lintCode --- Search a 2D Matrix II (探索二维矩阵)
- LeetCode题解(C++版)