难度:⭐
题目描述:
给你一个 m * n
的矩阵,矩阵中的数字 各不相同 。请你按 任意 顺序返回矩阵中的所有幸运数。
幸运数是指矩阵中满足同时下列两个条件的元素:
- 在同一行的所有元素中最小
- 在同一列的所有元素中最大
示例1:
1 | 输入:matrix = [[3,7,8],[9,11,13],[15,16,17]] |
示例2:
1 | 输入:matrix = [[1,10,4,2],[9,3,8,7],[15,16,17,12]] |
示例3:
1 | 输入:matrix = [[7,8],[1,2]] |
提示:
m == mat.length
n == mat[i].length
1 <= n, m <= 50
1 <= matrix[i][j] <= 10^5
- 矩阵中的所有元素都是不同的
解题过程:
思路:
暴力解法:遍历每一行,求出当前行中的最小元素,然后判断这个元素是否是所在列中的最大值,如果是则是幸运数,否则不是幸运数。
c++代码:(执行用时68ms,击败5.15%,内存消耗11.5M,击败17.44%)
1 | class Solution { |
官方题解:
方法一: 模拟
预处理出两个数组 rMin
和 cMax
,其中 rMin[i]
表示第 $i$ 行中最小的元素,cMax[j]
表示第 $j$ 列中最大的元素。接着遍历矩阵 matrix
,判断每个 matrix[i][j]
是否是这一行最小的并且是这一列最大的,具体方法是直接与 rMin[i]
和 cMax[j]
比较,如果都相等,就加入到答案的序列中。
思考:rMin
和 cMax
是否可以存放「行最小值」和「列最大值」的索引? 答案是可以。但是如果原题中没有说明「矩阵中的数字 各不相同」就不能这么干,因为假设第 rr 行的「行最小值」出现两次,索引为 $c_1$ 和 $c_2$c ,却只保存了一个索引 $c_1$,$c_2$位置的这个数满足它是「列最大值」,这个时候就会判断出错。
c++代码:(执行用时60ms,击败5.15%,内存消耗11.6M,击败7.41%)
1 | class Solution { |
复杂度分析
时间复杂度:预处理的时间代价是 $O(mn)$,统计答案的时间代价也是 $O(mn)$,故渐进时间复杂度为 $O(mn)$。
空间复杂度:这里用到了两个辅助数组
rMin
和cMax
,长度分别为 $m$ 和 $n$,故渐进空间复杂度为 $O(m + n)$。
总结:
本来我觉得暴力模拟解法太low了,想看看题解有没有什么更好的方法,结果官方题解也是暴力模拟🤣,不过官方题解和我的还是有一些不一样,他是先求出每行的最小值和每列的最大值,我是求出每行的最小值后再去判断是否是该列的最大值,他是并列关系,我是递进关系,不过效率也都差不多😗。