- 找出第 K 大的异或坐标值
给你一个二维矩阵 matrix 和一个整数 k ,矩阵大小为 m x n 由非负整数组成。
矩阵中坐标 (a, b) 的 值 可由对所有满足 0 <= i <= a < m 且 0 <= j <= b < n 的元素 matrix[i][j](下标从 0 开始计数)执行异或运算得到。
请你找出 matrix 的所有坐标中第 k 大的值(k 的值从 1 开始计数)。
示例 1:
输入:matrix = [[5,2],[1,6]], k = 1
输出:7
解释:坐标 (0,1) 的值是 5 XOR 2 = 7 ,为最大的值。
示例 2:
输入:matrix = [[5,2],[1,6]], k = 2
输出:5
解释:坐标 (0,0) 的值是 5 = 5 ,为第 2 大的值。
示例 3:
输入:matrix = [[5,2],[1,6]], k = 3
输出:4
解释:坐标 (1,0) 的值是 5 XOR 1 = 4 ,为第 3 大的值。
示例 4:
输入:matrix = [[5,2],[1,6]], k = 4
输出:0
解释:坐标 (1,1) 的值是 5 XOR 2 XOR 1 XOR 6 = 0 ,为第 4 大的值。
思路:首先思路还是前缀和,但是这次变成了二维前缀
通过模拟后我们得到前缀公式(这里的前缀和做出了修改,与行和列有关)
s u m [ i ] [ j ] = s u m [ i − 1 ] [ j ] 异 或 s u m [ i ] [ j − 1 ] 异 或 s u m [ i − 1 ] [ j − 1 ] 异 或 m a t [ i − 1 ] [ j − 1 ] ; sum[i][j] = sum[i - 1][j] 异或sum[i][j - 1] 异或 sum[i - 1][j - 1] 异或 mat[i - 1][j - 1]; sum[i][j]=sum[i−1][j]异或sum[i][j−1]异或sum[i−1][j−1]异或mat[i−1][j−1];
构建完前缀和后,我们就好做了,今天介绍的是暴力法
明天将结合优先队列来讲解
code1:
class Solution {
public int kthLargestValue(int[][] matrix, int k) {
LinkedList<Integer> list=new LinkedList<>();
int[][]sum=new int[matrix.length+1][matrix[0].length+1];
for(int i=1;i<=matrix.length;i++){
for(int j=1;j<=matrix[0].length;j++){
sum[i][j]=sum[i-1][j]^matrix[i-1][j-1]^sum[i][j-1]^sum[i-1][j-1];
}
}
// 计算得从0,0 到i,j的异或和
for(int i=1;i<=matrix.length;i++){
for(int j=1;j<=matrix[0].length;j++){
list.add(sum[i][j]);
}
}
Collections.sort(list);
return list.get(list.size()-k);
}
}
code2:
优先队列构建法:(明日将深度理解)
class Solution {
public int kthLargestValue(int[][] mat, int k) {
int m = mat.length, n = mat[0].length;
int[][] sum = new int[m + 1][n + 1];
PriorityQueue<Integer> q = new PriorityQueue<>(k, (a, b)->a - b);
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] ^ mat[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();
}
}