给你一个二维矩阵 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 大的值。
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 1000
0 <= matrix[i][j] <= 106
1 <= k <= m * n
提交代码:
public class KthLargestValue {
/**
* 先计算出异或结果,然后找出第K个大的值
* DP + 优先级队列(小顶堆)
* 第K大—小顶堆;第K小—大顶堆
*
* @param matrix
* @param k
* @return
*/
public static int kthLargestValue(int[][] matrix, int k) {
if (matrix == null || k < 1 || matrix.length * matrix[0].length < k) return 0;
int row = matrix.length;
int column = matrix[0].length;
int[][] dp = new int[row][column];
// 小顶堆
PriorityQueue<Integer> integerPriorityQueue = new PriorityQueue<>((o1, o2) -> o1.compareTo(o2));
dp[0][0] = matrix[0][0];
for (int i = 1; i < row; i++) {
dp[i][0] = dp[i - 1][0] ^ matrix[i][0];
}
for (int j = 1; j < column; j++) {
dp[0][j] = dp[0][j - 1] ^ matrix[0][j];
}
for (int i = 1; i < row; i++) {
for (int j = 1; j < column; j++) {
/**
* 出现的问题是
* XOR[i][j]异或的结果是matrix[0][0]~matrix[i-1][j-1] 与matrix[i - 1][j] ^ matrix[i][j - 1] ^ matrix[i][j]
* 的结果,丢失了matrix[i-1][0]~matrix[i-1[j-2] 以及matrix[0][j-1]~matrix[i-2][j-1]的元素异或结果
*/
// XOR[i][j] = XOR[i - 1][j - 1] ^ matrix[i - 1][j] ^ matrix[i][j - 1] ^ matrix[i][j];
dp[i][j] = dp[i - 1][j - 1] ^ dp[i - 1][j] ^ dp[i][j - 1] ^ matrix[i][j];
}
}
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
if (integerPriorityQueue.size() < k) {
integerPriorityQueue.add(dp[i][j]);
} else if (dp[i][j] > integerPriorityQueue.peek()) {
integerPriorityQueue.poll();
integerPriorityQueue.add(dp[i][j]);
}
}
}
return integerPriorityQueue.size() > 0 ? integerPriorityQueue.poll() : 0;
}
}
// 测试用例
public static void main(String[] args) {
int[][] matrix = new int[][]{{5, 2}, {1, 6}};
int k = 1;
int ans = KthLargestValue.kthLargestValue(matrix, k);
System.out.println("KthLargestValue demo01 result : " + ans);
matrix = new int[][]{{5, 2}, {1, 6}};
k = 2;
ans = KthLargestValue.kthLargestValue(matrix, k);
System.out.println("KthLargestValue demo02 result : " + ans);
matrix = new int[][]{{5, 2}, {1, 6}};
k = 3;
ans = KthLargestValue.kthLargestValue(matrix, k);
System.out.println("KthLargestValue demo03 result : " + ans);
matrix = new int[][]{{5, 2}, {1, 6}};
k = 4;
ans = KthLargestValue.kthLargestValue(matrix, k);
System.out.println("KthLargestValue demo04 result : " + ans);
// 1
matrix = new int[][]{{10, 9, 5}, {2, 0, 4}, {1, 0, 9}, {3, 4, 8}};
k = 10;
ans = KthLargestValue.kthLargestValue(matrix, k);
System.out.println("KthLargestValue demo05 result : " + ans);
}