本文正在参加「Java主题月 - Java 刷题打卡」,详情查看 活动链接
题目描述
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
每行中的整数从左到右按升序排列。 每行的第一个整数大于前一行的最后一个整数。
示例 1:
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
输出:true
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-a-2d-matrix
思路分析
- 这个题目题意容易理解,有多种方法可以解决。
- 首先可以采用 HashMap 的方式以空间换时间高效查找解决。缺点是没有利用题目提示的矩阵特征。
- 也可以采取两次二分查找,同时利用矩阵特点,提升查询效率。优点是无需额外空间,查询效率高。
AC代码
- HashMap 解法
public class DayCode {
public static void main(String[] args) {
int[][] matrix = {{1, 3, 5, 7}, {10, 11, 16, 20}, {23, 30, 34, 60}};
int target = 3;
boolean ans = new DayCode().searchMatrix(matrix, target);
System.out.println(ans);
}
/**
* 时间复杂度 O (m * n)
* 空间复杂度 O (m * n)
* @param matrix
* @param target
* @return
*/
public boolean searchMatrix(int[][] matrix, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix[row].length; col++) {
map.put(matrix[row][col], matrix[row][col]);
}
}
return map.containsKey(target);
}
}
- 二分查找方法
public class DayCode {
public static void main(String[] args) {
int[][] matrix = {{1, 3, 5, 7}, {10, 11, 16, 20}, {23, 30, 34, 60}};
int target = 3;
boolean ans1 = new DayCode().searchMatrix1(matrix, target);
System.out.println(ans1);
}
/**
* 时间复杂度 O(log (m + n))
* 空间复杂度 O(1)
* @param matrix
* @param target
* @return
*/
public boolean searchMatrix1(int[][] matrix, int target) {
int rowIdx = binarySearchFirstColumn(matrix, target);
if (rowIdx < 0) {
return false;
}
return binarySearchRow(matrix[rowIdx], target);
}
private boolean binarySearchRow(int[] matrix, int target) {
int left = 0, right = matrix.length - 1;
while (left <= right) {
int mid = (right - left) / 2 + left;
if (matrix[mid] == target) {
return true;
} else if (matrix[mid] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return false;
}
private int binarySearchFirstColumn(int[][] matrix, int target) {
int low = -1, high = matrix.length - 1;
while (low < high) {
int mid = (high - low + 1) / 2 + low;
if (matrix[mid][0] <= target) {
low = mid;
} else {
high = mid - 1;
}
}
return low;
}
}
提交测试:
总结
- HashMap 解法的时间复杂度 O (m * n),空间复杂度 O (m * n)
- 二分查找 解法的时间复杂度 O(log (m + n)),空间复杂度 O(1)
- 坚持每日一题,加油!