二分查找要注意边界值的取值,边界情况的判定
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
示例 1:
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
输出:true
示例 2:
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
输出:false
提示:
解法一 先搜索在哪一行再搜索某一行
算法复杂度\(O(m+n)\)
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int len = matrix.length;
int n = matrix[0].length;
for (int i = 0; i < len ; ++i) {
if (target >= matrix[i][0] && i + 1 <= len - 1 && target < matrix[i+1][0]) {
for (int j = 0; j < n; ++j) {
if (matrix[i][j] == target) {
return true;
}
}
}
else if (target >= matrix[i][0] && i == len - 1) {
for (int j = 0; j < n; ++j) {
if (matrix[i][j] == target) {
return true;
}
}
}
}
return false;
}
}
解法二 在解法一的基础上二分查找
算法复杂度\(O(log(mn))\)
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length;
int n = matrix[0].length;
int m1 = findm(matrix, target, 0, m-1);
if (m1==-1) {return false;}
return findn(matrix[m1], target, 0, n-1);
}
public int findm(int[][] matrix, int target, int s, int t) {
if (s == t) {
return target >= matrix[s][0] && target <= matrix[s][matrix[0].length-1] ? s : -1;
}
int mid = (s + t) >> 1;
if (target >= matrix[mid][0] && target < matrix[mid+1][0]) {
return mid;
}
else if (target > matrix[mid][0]) {
// 这里选择 mid+1 是为什么,细品一下
return findm(matrix, target, mid + 1, t);
}
else {
// 这里选择 mid 为什么不是 mid-1,继续品
return findm(matrix, target, s, mid);
}
}
public boolean findn(int[] matrix, int target, int s, int t) {
if (s == t) {
return matrix[s] == target || matrix[t] == target;
}
int mid = (s + t) >> 1;
if (target == matrix[mid]) {
return true;
}
else if (matrix[mid] < target) {
return findn(matrix, target, mid + 1, t);
}
else {
return findn(matrix, target, s, mid);
}
}
}
解法三 将二维数组当做一维数组,二分查找
算法复杂度为\(O(log(m+n))\)
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length;
int n = matrix[0].length;
int pi = 0, pj = m * n - 1;
while (pj > pi) {
int mid = (pi + pj) >> 1;
int i = mid / n;
int j = mid % n;
if (matrix[i][j] == target) {
return true;
}
else if (matrix[i][j] > target) {
pj = mid;
continue;
}
else {
pi = mid + 1;
continue;
}
}
if (pi == pj) {
int i = pi / n;
int j = pi % n;
return matrix[i][j] == target;
}
return false;
}
}
leetcode 刷题(数组篇)74 题 搜索二维矩阵 (二分查找)
原文:https://www.cnblogs.com/XiiX/p/14657437.html