本文正在参加「Java主题月 - Java 刷题打卡」,详情查看 活动链接
题目
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/fi…
给你一个二维矩阵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.lengthn == matrix[i].length1 <= m, n <= 10000 <= matrix[i][j] <= 1061 <= k <= m * n
题目分析
首先明确一下题目的意思
比如示例中给了一个2 X 2 的矩阵[[5,2],[1,6]]
5 2
1 6
-
坐标
(0,0)的值就是(0,0)位置的异或其实就是5; -
坐标
(0,1)的值是(0,0)与(0,1)的异或5⊕2 = 3; -
坐标
(1,0)的值是(0,0)与(1,0)的异或5⊕1=4; -
坐标(1,1)的值是
(0,0),(0,1),(1,0)与(1,1)的异或``5⊕2⊕1⊕6= 0`; -
求第
k大的值就是求[5,3,4,0]中第k大的值
假设sum[i][j]表示坐标(i,j)的值,那么**sum[i][j] = sum[i-1][j] ^ sum[i][j] ^ sum[i-1][j-1] ^ matrix[i][j]**
要求图中(i,j)的值(表示为sum[i][j]),就是图中9个元素的异或值,其中红色部分加黄色部分是sum(i,j-1),绿色部分加黄色部分是sum[i-1][j],如果直接``sum(i,j-1) ^sum[i-1][j] 的话,显然黄色部分算了两次,**一个数与本身异或结果是0**,黄色部分变成0了,**一个数与0异或还是这个数本身**,所以再加上黄色部分sum[i-1][j-1]`就OK了
public class Solution {
public int kthLargestValue(int[][] matrix, int k) {
int m = matrix.length;
int n = matrix[0].length;
// 将行列都扩大一位,避免边界值判断
int[][] sum = new int[m + 1][n + 1];
List<Integer> result = new ArrayList<>();
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
sum[i][j] = sum[i][j - 1] ^ sum[i - 1][j] ^ sum[i - 1][j - 1] ^ matrix[i - 1][j - 1];
result.add(sum[i][j]);
}
}
List<Integer> orderList = result.stream().sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
return orderList.get(k - 1);
}
}
总结
双层循环时间复杂度就是O(mn)了,最后的排序用来java的sort,这个应该不是重点
按位异或运算与满足交换律与结合律