题目描述
思路
模拟
遍历矩阵,判断matrix[i][j]是否是所在行的最小值和所在列的最大值,如果是,则加入返回结果。但实际上,这样的点至多有一个。
为什么呢?
假定有两个点(x1, y1)和(x2, y2)都是幸运数,则有
matrix[x1][y1] <= matrix[x1][y2]
matrix[x1][y1] >= matrix[]x2][y1]
matrix[x2][y2] <= matrix[x2][y1]
matrix[x2][y2] >= matrix[x1][y2]
则有如下结论:
matrix[x2][y2] >=matrix[x1][y2] >= matrix[x1][y1]
matrix[x1][y1] >= matrix[x2][y1] >= matrix[x2][y2]
所以只有可能
m
a
t
r
i
x
[
x
1
]
[
y
1
]
=
=
m
a
t
r
i
x
[
x
2
]
[
y
2
]
matrix[x1][y1] == matrix[x2][y2]
matrix[x1][y1]==matrix[x2][y2],但是根据题意,矩阵中的数字各不相同,所以矛盾。所以幸运数至多有一个。
这个值会出现在哪里呢?显然就是所有行最小值的最大值与所有列最大值的最小值一致的情况,如果不一致,则没有幸运数。
假设取的不是行的最小值的最小值,设取的行r1,则一定存在某一行r2的最小值大于r1。则r1的最小值那一列是一定小于r2的该列的值的,因为最小值比r2的最小值还小,所以这样的r1的最小值必然不满足是该列的最大值。所以必然要取行的最小值的最大值。同理可证必须取列的最大值的最小值。又因为答案最多一个,所以只有当这两个值相等,才为答案。
Python实现
class Solution:
def luckyNumbers (self, matrix: List[List[int]]) -> List[int]:
return [a] if (a := max(min(m) for m in matrix)) == (b := min(max(m) for m in zip(*matrix))) else []
Java实现
class Solution {
public List<Integer> luckyNumbers (int[][] matrix) {
int a = 0, b = 100005;
for (int i = 0; i < matrix.length; ++i) {
int cur = 100005;
for (int j = 0; j < matrix[0].length; ++j) {
cur = Math.min(cur, matrix[i][j]);
}
a = Math.max(a, cur);
}
for (int j = 0; j < matrix[0].length; ++j) {
int cur = 0;
for (int i = 0; i < matrix.length; ++i) {
cur = Math.max(cur, matrix[i][j]);
}
b = Math.min(b, cur);
}
List<Integer> ans = new ArrayList<>();
if (a == b) {
ans.add(a);
}
return ans;
}
}