leetcode
leetcode 2801 ~ 2850
排序矩阵查找

排序矩阵查找

难度:

标签:

题目描述

Given an M x N matrix in which each row and each column is sorted in ascending order, write a method to find an element.

Example:

Given 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]
]

Given target = 5, return true.

Given target = 20, return false.

代码结果

运行时间: 26 ms, 内存: 20.4 MB


/**
 * Given an MxN matrix where each row and each column is sorted in ascending order, 
 * write a code to find a specific element using Java Streams.
 * 
 * Approach:
 * We can use the same logic as above but filter rows and columns with Streams. 
 * We can flatten the 2D matrix into a stream and check for the target using anyMatch.
 */

import java.util.Arrays;

public class MatrixSearchStream {
    public boolean searchMatrix(int[][] matrix, int target) {
        return Arrays.stream(matrix)
                     .flatMapToInt(Arrays::stream)
                     .anyMatch(x -> x == target);
    }
}

解释

方法:

该题解采用的是逐行扫描的方法。首先,检查矩阵是否为空。对于每一行,如果该行的最后一个元素大于或等于目标值,则在该行中逐个检查元素是否等于目标值。这种方法是基于每行和每列都是升序的事实,如果某行的最后一个元素已经小于目标值,那么目标值不可能出现在当前行或之前的行中。

时间复杂度:

O(MN)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么逐行扫描选择检查行的最后一个元素而不是第一个元素来决定是否在该行继续查找?
在给定的矩阵中,每一行和每一列都是升序排列的。如果在某一行的扫描过程中,我们检查了最后一个元素并发现它小于目标值,那么这意味着当前行及其之前的所有行都不可能包含目标值,因为这些行的所有元素都会小于或等于这一行的最后一个元素。反之,如果检查第一个元素,无论其值如何,都无法提供类似的有用信息,因为即使第一个元素大于目标值,目标值仍可能出现在行中的其他位置。因此,检查每行的最后一个元素是一种更有效的筛选方式,可以快速确定目标值是否可能存在于该行。
🦆
如果矩阵的行数远大于列数,或者列数远大于行数,这种方法的效率如何?是否有更优的搜索方法?
如果矩阵的行数远大于列数,逐行扫描然后在行内逐元素检查的效率可能会较低,因为即使使用行的最后一个元素进行初步过滤,仍需对许多行进行完整扫描。同理,如果列数远大于行数,问题同样存在。在这种情况下,更优的搜索方法是使用类似于二分搜索的方法,称为分步搜索(也被称为'从右上角开始'或'从左下角开始'的搜索方法)。这种方法在每一步中都利用矩阵的行和列的有序性来排除行或列,从而更快地缩小搜索范围,提高效率。
🦆
代码中的`if len(matrix)==0 or len(matrix[0])==0`检查是为了处理什么特殊情况?能否给出一个具体的例子?
该检查是为了处理矩阵为空或矩阵中某些行为空的情况。这是边界情况处理,确保在执行任何进一步操作之前,输入的矩阵是有效的。例如,如果输入的矩阵是`[]`(即没有行的矩阵),或者是`[[]]`(即有一行但该行没有元素),这两种情况下,矩阵都不包含任何元素,因此无论目标值是什么,搜索结果应该是`False`。此检查确保程序在尝试访问元素之前不会因为这些无效的输入而出现错误。

相关问题