LC 100124. 找出强数对的最大异或值 II
https://leetcode.cn/problems/maximum-strong-pair-xor-ii/
这题大概思路是先求解y的特性,然后看看怎么快速地从符合条件的y里面找到异或最大值。
如果x<=y的话,那么可以得到 x <= y <= 2 * x. 所以我们只需要维护一个数据结构,这个数据结构里面都是 x <= y <= 2 * x 的值就行。这个用双指针就可以搞定。
接着就是这个数据结构了。要求接异或最大值的话,最直接的办法就是维护0,1的二叉树。鉴于其实nums[i]值的范围在[0,2^20)以内,所以这个二叉树可以使用树状数组来实现。
我们每次需要从这个数据结构里面删除和加入某些值的分支,并且更新分支上的值,这个数据结构就是线段树。
最后就是其实判断分支的方法可以写成许多的if-else, 但是也可以简化成下面这样的方式 `p = 2 * p + (1 - b)` 或者是 `p = 2 * p + b`. 代码看起来会更加简单。
这里使用的是 `(p-N)^x` 计算最后的xor结果,在搜索路径上我们其实也可以得到 xor 之后的值。
#!/usr/bin/env python
# coding:utf-8
# Copyright (C) dirlt
from typing import List
class Solution:
def maximumStrongPairXor(self, nums: List[int]) -> int:
nums.sort()
MAXB = 20
N = 1 << MAXB
tree = [0] * (2 * N)
def update(x, v):
p = N + x
tree[p] = v
while p != 1:
p2 = p // 2
tree[p2] = tree[2 * p2] + tree[2 * p2 + 1]
p = p2
def search(x):
p = 1
if tree[p] == 0: return 0
for i in reversed(range(MAXB)):
b = (x >> i) & 0x1
p2 = 2 * p + (1 - b)
if not tree[p2]:
p2 = 2 * p + b
p = p2
assert (tree[p])
return (p - N) ^ x
j, k = 0, 0
ans = 0
for i in range(len(nums)):
while j < i:
update(nums[j], 0)
j += 1
while k < len(nums) and nums[k] <= 2 * nums[i]:
update(nums[k], 1)
k += 1
r = search(nums[i])
ans = max(ans, r)
return ans