题目描述
给你一个二维矩阵 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 异或 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 异或 1 = 4 ,为第 3 大的值。
示例 4:
输入:matrix = [[5,2],[1,6]], k = 4
输出:0
解释:坐标 (1,1) 的值是 5 异或 2 异或 1 异或 6 = 0 ,为第 4 大的值。
思路
- 题目要找出所有坐标中的第 k 大的值,那么首先想到的一点就是把所有的坐标都求出来,然后排序得到第 k 大的值。
- 那么怎么求所有的坐标呢?这里使用一个 dp 进行递推,画出一个二维矩阵,根据题意,很容易的可以发现 dp[i][j] = dp[i-1][j] ^ dp[i][j-1] ^ dp[i-1][j-1] ^ matrix[i][j]。
- dp的边界条件为,dp[0][0] = matrix[0][0],dp[0][i] = dp[0][i-1] ^ matrix[0][i],dp[j][0] = dp[j-1][0] ^ matrix[j][0]
- 有了边界条件和递推式之后,就可以用两层循环获得dp啦。在计算出每一个dp的值之后,就将该值加入一个 List 中,方便后面排序。
- 时间复杂度/空间复杂度,均为O( mn*log(mn) )
代码
class Solution {
public int kthLargestValue(int[][] matrix, int k) {
int row = matrix.length;
int col = matrix[0].length;
int [][]dp = new int[row][col];
List <Integer> res = new ArrayList<Integer>();
dp[0][0] = matrix[0][0];
res.add(dp[0][0]);
//0行0列边界条件
for(int i = 1;i < col;i++) {
dp[0][i] = dp[0][i-1]^matrix[0][i];
res.add(dp[0][i]);
}
for(int j = 1;j < row;j++) {
dp[j][0] = dp[j-1][0]^matrix[j][0];
res.add(dp[j][0]);
}
for(int i = 1;i < row;i++) {
for(int j = 1;j < col;j++) {
dp[i][j] = dp[i-1][j-1]^dp[i-1][j]^dp[i][j-1]^matrix[i][j];
res.add(dp[i][j]);
}
}
//对res排序
Comparator<Integer> c = new Comparator<Integer>() {
public int compare(Integer a, Integer b) {
return b - a;
}
};
Collections.sort(res, c);
return res.get(k-1);
}
}