这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战
前言
- 为了年后准备的目标,现在还是要多刷刷LeetCode滴 !-_-!
二分查找
- 这次看了LeetCode上一道二分查找的算法题,题如下:
74. 搜索二维矩阵
编写一个高效的算法来判断 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
- 根据题中给出的特性:每行数组中从左到右升序排列,而且每行的第一个整数大于前一行的最后一个整数。很明显解题思路可以按照二分查找进行解题。
解题方式一
- 首先可以通过对二维数组进行二分查找,判断当前target在哪一列的数组。
- 然后在对列上数组进行二分查找,进而找到具体值
- 编码如下:
/**
* 搜索二维矩阵
* 编写一个高效的算法来判断m x n矩阵中,是否存在一个目标值。该矩阵具有如下特性:
* 每行中的整数从左到右按升序排列。
* 每行的第一个整数大于前一行的最后一个整数。
*
* @Author: ZRH
* @Date: 2022/2/7 14:48
*/
public class Num74 {
public static void main (String[] args) {
int[][] matrix = new int[][]{{1, 3, 5, 7}, {10, 11, 16, 20}, {23, 30, 34, 60}};
System.out.println(searchMatrix(matrix, 3));
matrix = new int[][]{{1, 3, 5, 7}, {10, 11, 16, 20}, {23, 30, 34, 60}};
System.out.println(searchMatrix(matrix, 13));
}
public static boolean searchMatrix (int[][] matrix, int target) {
// 获取二维数组的宽、高
int m = matrix.length - 1;
int n = matrix[m].length - 1;
// 首节点或尾节点判断
if (matrix[0][0] > target || matrix[m][n] < target) {
return false;
}
// 二分的左右边界、
int l = 0, r = m, mid;
while (l <= r) {
// 对半取值
mid = l + (r - l) / 2;
// mid节点的数组边界判断
if (matrix[mid][0] == target || matrix[mid][n] == target) {
return true;
}
// target在当前二分的左边
if (target < matrix[mid][0]) {
// 右边节点往左移动
r = mid - 1;
} else {
// target在当前二分的右边
if (matrix[mid][n] >= target) {
// target在列数组上再次进行二分查找
int l1 = 0, r1 = n, mid1;
while (l1 <= r1) {
// 对半取值,并判断验证结果
mid1 = l1 + (r1 - l1) / 2;
if (matrix[mid][mid1] == target) {
return true;
}
if (target < matrix[mid][mid1]) {
// 右边节点往左移动
r1 = mid1 - 1;
} else {
// 左边节点往右移动
l1 = mid1 + 1;
}
}
return false;
} else {
// 左边节点往右移动
l = mid + 1;
}
}
}
return false;
}
}
---------------- 打印结果:
true
false
解题方式二
- 从总体看整个二维数组从左到右,从上到下都是有序的。
- 那么把当前行的数组头节点和上一行的数组尾结点进行拼接,最后就可以组成一个有序的数组,然后进行二分查找也是可以的。
- 编码就不编码了,二分查找的思路大体都是一样。
最后
- 虚心学习,共同进步-_-