总结
-
知识点
- 排序数组查找元素,二分法
- 排序二维数组一是一样的用二分。
-
二维矩阵的行和列是排好序的
- 分为好几种情况:行排序,列没有排序;行排序,列排序
- 行排序,列排序:看成二叉有序树,从左下角开始,向右后向上找到元素
- 行排序,列没有排序,但每行的第一个整数大于前一行的最后一个整数。看成一个整排数组。二分,index 对列数的余数,除数做下标到二维数组中找元素。
题目 240_搜索二维矩阵 II
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:
每行的元素从左到右升序排列。
每列的元素从上到下升序排列。
示例:
现有矩阵 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]
]
给定 target = 5,返回 true。
给定 target = 20,返回 false。
思路
- 这个矩阵太特殊了,行从左到右升,列从上到下升
以左下角的元素作为起点,将起点看成是一个二叉有序树的根节点
左节点(上面)小于根节点,右节点(右边)大于根节点
像搜索二叉树搜索二维数组
如果nums[i][j] > target, 那么向上走
如果nums[i][j] < target, 那么像右走,
结束条件: 找到 return
超出返回: 二叉树到边界叶子节点,二维数组到 边界 0 <= i < n ; 0 <= j < m
出错:
- 输入: []
class Solution {
public boolean searchMatrix(int[][] nums, int target) {
if(nums == null || nums.length == 0) return false;
if(nums[0] == null || nums[0].length == 0) return false;
int n = nums.length;
int m = nums[0].length;
int i = n - 1, j = 0;
while(i >= 0 && (i < n) && (j >= 0) && j < m) {
if(nums[i][j] < target) {
j = j + 1; // 往右走
}else if(nums[i][j] > target) {
i = i - 1; // 往上走
}else if(nums[i][j] == target){
return true;
}
}
return false;
}
}
题目 74_搜索二维矩阵
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
每行中的整数从左到右按升序排列。
每行的第一个整数大于前一行的最后一个整数。
示例 1:
输入:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 3
输出: true
示例 2:
输入:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 13
输出: false
思路
- 二分法 因为二维数组每一行的起始元素比上一行的末尾元素要大,所以展开成一维数组,递增
- idx: 0 ~ m*n - 1
- matrix[ idx / n ] [ idx % n] 是展开idx对应的二维数组上的元素
图片:https://leetcode-cn.com/problems/search-a-2d-matrix/solution/sou-suo-er-wei-ju-zhen-by-leetcode/
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
if(matrix == null || matrix.length == 0) return false;
if(matrix[0] == null || matrix[0].length == 0) return false;
int m = matrix.length, n = matrix[0].length;
int left = 0, right = m * n - 1;
while(left <= right) {
int mid = left + (right - left) / 2;
if(matrix[mid / n][mid % n] < target) {
left = mid + 1;
}else if(matrix[mid / n][mid % n] > target) {
right = mid - 1;
}else{
return true;
}
}
return false;
}
}