力扣 1738. 找出第 K 大的异或坐标值

题目说明

  • 给你一个二维矩阵 matrix 和一个整数 k ,矩阵大小为 m x n 由非负整数组成。

    矩阵中坐标 (a, b) 可由对所有满足 0 <= i <= a < m0 <= j <= b < n 的元素 matrix[i][j]下标从 0 开始计数)执行异或运算得到。

    请你找出 matrix 的所有坐标中第 k 大的值(**k 的值从 1 开始计数**)。

  • 提示:
    • m == matrix.length
    • n == matrix[i].length
    • 1 <= m, n <= 1000
    • 0 <= matrix[i][j] <= 106
    • 1 <= k <= m * n

示例

示例 1:

1
2
3
输入:matrix = [[5,2],[1,6]], k = 1
输出:7
解释:坐标 (0,1) 的值是 5 XOR 2 = 7 ,为最大的值。

示例 2:

1
2
3
输入:matrix = [[5,2],[1,6]], k = 2
输出:5
解释:坐标 (0,0) 的值是 5 = 5 ,为第 2 大的值。

示例 3:

1
2
3
输入:matrix = [[5,2],[1,6]], k = 3
输出:4
解释:坐标 (1,0) 的值是 5 XOR 1 = 4 ,为第 3 大的值。

示例 4:

1
2
3
输入:matrix = [[5,2],[1,6]], k = 4
输出:0
解释:坐标 (1,1) 的值是 5 XOR 2 XOR 1 XOR 6 = 0 ,为第 4 大的值。

笔者理解

此题是一道位运算算法问题,在力扣题库中被定义为中等题。

解法

当笔者阅读完此题后,发现此题用二维数组直接存储异或异或计算值,再使用优先队列(小顶堆)存储k个元素即可求解,让我们来看看具体如何实现的吧。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public int kthLargestValue(int[][] matrix, int k) {
int m = matrix.length, n = matrix[0].length;

// 异或二维数组
int[][] sum = new int[m + 1][n + 1];

// 用优先队列来存储值
PriorityQueue<Integer> q = new PriorityQueue<>(k);

for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
// 异或性质
sum[i][j] = sum[i - 1][j] ^ sum[i][j - 1] ^ sum[i - 1][j - 1] ^ matrix[i - 1][j - 1];

if (q.size() < k) {
q.add(sum[i][j]);
}
else if (sum[i][j] > q.peek()) {
q.poll();
q.add(sum[i][j]);
}
}
}
return q.peek();
}

空间有点差,毕竟是二维数组,时间效率还行,可见此解法还比较适合此题;

image-20210519213842464

总结

本题是今天的每日一题,难度是为中等,感兴趣的朋友都可以去尝试一下,此题还有其他更多的解法,朋友们可以自己逐一尝试。