📌  相关文章
📜  从给定数组中删除最多 K 个元素后的最小按位或(1)

📅  最后修改于: 2023-12-03 14:49:27.390000             🧑  作者: Mango

从给定数组中删除最多 K 个元素后的最小按位或

在给定一个长度为 n 的数组 nums 和一个整数 k,你需要删除最多 k 个元素,使得剩下的元素的按位或值最小,返回这个最小值。

解法

为了使剩下的元素的按位或值最小,我们需要尽可能地保留高位上的 1,因为一个数的按位或值至少是这个数本身,而且每一位上的 1 都会让这个值更大。

因此,我们可以枚举从高到低第 i 位上是否保留 1。如果保留了这个 1,我们就将所有最高位是 1 且第 i 位是 0 的数从数组中删除,直到数组中剩下的数的按位或值大于等于当前答案(因为如果按位或值小于当前答案,那么我们必须删除更多的数才能使其大于等于当前答案,而这是不利于我们使答案更小的)。最后,如果按位或值小于当前答案,我们就保留这一位上的 1;否则我们就将这一位上的 1 删除。

下面是详细的算法代码:

def minimum_or(nums, k):
    n = len(nums)
    ans = 0
    for i in range(30, -1, -1):
        cnt_zero = 0
        max_or = 0
        cur_or = 0
        for j in range(n):
            if (nums[j] >> i) & 1 == 1:
                cur_or |= nums[j]
            else:
                cnt_zero += 1
                max_or = max(max_or, cur_or)
                cur_or = 0
        max_or = max(max_or, cur_or)
        if max_or < ans | (1 << i):
            ans |= 1 << i
        elif cnt_zero <= k:
            k -= cnt_zero
        else:
            ans |= 1 << i
            k -= k
    return ans
复杂度分析

时间复杂度:$O(n \log W)$,其中 W 表示元素最大值的位数。在每个位上,我们需要枚举一遍数组并计算按位或值,时间复杂度为 $O(n)$。而最高位有 $\log W$ 个,因此总时间复杂度为 $O(n \log W)$。

空间复杂度:$O(1)$。我们只需要常数个额外的变量来保存一些状态。