📅  最后修改于: 2023-12-03 15:12:30.715000             🧑  作者: Mango
给定两个长度相等的整数数组 nums1
和 nums2
,重新排列 nums1
中的数字,使得它们的按位与(bitwise AND)之和最大化。请你返回重新排列后的数组中按位与的总和。
输入:
nums1 = [3, 1, 5, 7, 9]
nums2 = [2, 6, 4, 8, 10]
输出:
最大化的按位与之和为 120。
将 nums1 中的数字重新排列得到 [9, 3, 5, 1, 7],
两个数组按位与的总和是 9&2 + 3&6 + 5&4 + 1&8 + 7&10 = 120。
题目要求我们最大化两个数组中相同索引位置上的元素的按位与,因此我们可以考虑在保证按位与结果不变的情况下,尽可能地将 nums1
中的较大元素放置到能够与 nums2
中相同索引位置上的元素按位与得到较大结果的位置上。
具体来说,对于 nums1
中的元素,我们可以将其拆分为二进制位表示形式,然后从高位到低位进行排列。这样可以保证将高位上的 1 尽量与 nums2
中相同索引位置上的元素的高位上的 1 进行按位与,从而尽可能地提高按位与结果。
from typing import List
class Solution:
def maximizeXor(self, nums1: List[int], nums2: List[int]) -> int:
# 对 nums1 中的元素进行排序
nums1.sort(reverse=True)
ans, n = 0, len(nums1)
# 枚举 nums2 中的元素,以确定最大化按位与结果的最佳排列方式
for num2 in nums2:
for i in range(n):
# 拆分 nums1[i] 为二进制表示形式
temp = [0] * 31
idx = 0
while nums1[i]:
temp[idx] = nums1[i] % 2
nums1[i] //= 2
idx += 1
# 将 nums1[i] 与 num2 从高位到低位进行按位与
j, cur = 30, 0
while j >= 0 and temp[j] == 0:
j -= 1
while j >= 0 and temp[j] == 1:
cur = cur * 2 + (num2 >> j & 1)
j -= 1
while j >= 0:
cur = cur * 2
j -= 1
# 更新最大化按位与结果
ans += cur
return ans
nums1
中的每个元素拆分为二进制位表示形式,并进行排序,因此时间复杂度为 $O(n \log n)$;同时,我们需要枚举 nums2
中的每个元素,并从高位到低位进行按位与运算,因此时间复杂度为 $O(31n)$,即 $O(n)$。又因为 $n \log n$ 在渐进意义下大于 $n$,因此总时间复杂度为 $O(n \log n)$。nums1
,以及一个长度为 31 的数组来存储拆分后的二进制位表示形式。