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

目录

题目解析 | 查找二维矩阵中所有坐标的第 K 大前缀异或值

题目描述

问题拆解与解题分析

1. 异或的性质

2. 什么是“前缀异或数组”

3. 计算 prefix[i][j]

4. 收集所有目标值,排序返回第 k 大

代码实现(Python)

复杂度分析

优化建议

示例说明

总结


题目解析 | 查找二维矩阵中所有坐标的第 K 大前缀异或值

题目描述

给你一个大小为 m x n 的二维矩阵 matrix,矩阵中的元素均为非负整数。定义坐标 (a, b)目标值为:

(a, b) 为右下角,左上角固定为 (0, 0) 的子矩阵中所有元素的异或结果。

换句话说,目标值是对所有满足 0 <= i <= a < m0 <= j <= b < n 的元素 matrix[i][j] 做异或运算后的结果。

请你找出矩阵中所有坐标的目标值中第 k 大的值。k 从 1 开始计数。


问题拆解与解题分析

1. 异或的性质

  • 异或运算有结合律和交换律
  • 异或自身为零:x ^ x = 0
  • 任何数与零异或结果是其自身:x ^ 0 = x

这些性质使得计算前缀异或和成为可能,类似前缀和的思想。

2. 什么是“前缀异或数组”

我们定义一个二维数组 prefix,其中prefix[i][j] = matrix[0][0] \oplus matrix[0][1] \oplus \cdots \oplus matrix[i][j]

(0,0)(i,j) 的矩阵子区域内所有元素的异或和。

这样一来,目标值 (a,b) 就可以直接通过 prefix[a][b] 得到。

3. 计算 prefix[i][j]

如何计算 prefix

观察发现:

prefix[i][j] = prefix[i-1][j] \oplus prefix[i][j-1] \oplus prefix[i-1][j-1] \oplus matrix[i][j]

  • prefix[i-1][j]prefix[i][j-1] 是分别从上和左获得的异或值
  • prefix[i-1][j-1] 因为加了两次,需要异或回去
  • 再异或当前元素 matrix[i][j]

4. 收集所有目标值,排序返回第 k 大

计算完成所有的 prefix[i][j],把它们放进列表里。

对列表进行降序排序后,取第 k 个元素即可。


代码实现(Python)

from typing import List

class Solution:
    def kthLargestValue(self, matrix: List[List[int]], k: int) -> int:
        m, n = len(matrix), len(matrix[0])
        prefix = [[0] * n for _ in range(m)]
        values = []

        for i in range(m):
            for j in range(n):
                top = prefix[i-1][j] if i > 0 else 0
                left = prefix[i][j-1] if j > 0 else 0
                top_left = prefix[i-1][j-1] if i > 0 and j > 0 else 0
                prefix[i][j] = top ^ left ^ top_left ^ matrix[i][j]
                values.append(prefix[i][j])

        values.sort(reverse=True)
        return values[k-1]

复杂度分析

时间复杂度
计算前缀异或需要遍历矩阵所有元素,时间为 O(m*n),排序所有目标值(共有 m*n 个)需要 O(m*n log(m*n)),因此总时间复杂度为:

  • O(m×nlog⁡(m×n))
  • 空间复杂度
    需要存储 prefix 数组和 values 列表,均为 O(m*n)

优化建议

k 比较小,但矩阵很大时,排序所有元素显得效率不高。可以使用大小为 k 的最小堆维护 top k 大的元素:

  • 遍历所有 prefix[i][j]
  • 将元素放入最小堆,堆大小超过 k 时弹出最小元素
  • 最终堆顶即为第 k 大元素

这样,维护堆的时间复杂度为 O(m*n * log k),相比完全排序可能更快。


示例说明

举个例子:

matrix = [
  [5, 2],
  [1, 6]
]
k = 2
  • 计算 prefix 数组:

i\j

0

1

0

5

5 ^ 2 = 7

1

5 ^ 1 = 4

5 ^ 2 ^ 1 ^ 6 = 3

所以 prefix = [[5,7],[4,3]]

  • 所有目标值是 [5,7,4,3]
  • 降序排列是 [7,5,4,3]
  • 第 2 大是 5

总结

本题关键在于利用前缀异或数组,将复杂的矩阵区域异或查询降维为 O(1) 的查询,极大提升计算效率。

常规做法是计算所有目标值并排序,但在大规模数据下,堆优化可以显著降低时间开销。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值