SDE / Intern · OA

Amazon OA:加法预算下,选 M 个数最大化 Bitwise AND

从高位到低位试掩码,以每个数满足掩码的最小增量及 M 个最低成本判断可行。

题目重点:从高位到低位试掩码,以每个数满足掩码的最小增量及 M 个最低成本判断可行。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 整数非负、允许任意分配加法预算、选择恰好m个不同位置;无需连续。
  • 不允许减值,预算可不花完;固定宽度环境另定溢出界。

解题路线

  1. 可行掩码t表示存在m项最终数都包含t的每个1位,即(y&t)==t;它不要求最终数恰等于t,也不要求AND恰等于t。
  2. 对原值a,找t中a缺少的最高位b。若无缺位,cost=0。否则保留a在b之上的前缀,把b置1,再让低位恰为t所需低位;这给最小满足条件且≥a的y。
  3. 为什么最小:保持高前缀时b必须从0变1,因此低位可以清零再填必要位;若改变更高前缀使值更大,必不优于该构造。用加法可能清除低位,所以不能直接把(a|t)-a当所有情况的最小成本。
  4. 计算所有项cost,选m个最小值的和;彼此增量独立,因此这个和≤预算当且仅当该掩码可行。选择过程可改变,不锁定前一次选中的m项。
  5. 高位优先试answer|2^b,可行就保留,否则放弃。可行性对删除1位封闭,任意更高首差位优先于全部低位和,故逐位得到最大整数AND。最高可能位用max(a)+budget界定。

手动走一遍

题目输入[5,4,1,7,2]、m=3、budget=3可将4和5增至6,选原值4、5、7得到6&6&7=6,花3;作者写“选4,5,6”中的6不在输入,本文明确修正。另a=3,t=4最小y=4仅花1,OR得到7花4会错。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

def increment_cost(value, mask):
    """Smallest y >= value such that y & mask == mask, minus value."""
    missing = mask & ~value
    if not missing:
        return 0
    bit = missing.bit_length()-1
    lower = (1 << bit)-1
    target = (value >> (bit+1) << (bit+1)) + (1 << bit) + (mask & lower)
    return target-value


def maximize_and(values, selected_count, budget):
    if not 1 <= selected_count <= len(values) or budget < 0 or any(v < 0 for v in values):
        raise ValueError("invalid nonnegative input or selection size")
    answer = 0
    for bit in range((max(values)+budget).bit_length()-1,-1,-1):
        candidate = answer | (1 << bit)
        costs = sorted(increment_cost(v,candidate) for v in values)
        if sum(costs[:selected_count]) <= budget:
            answer = candidate
    return answer

复杂度

B个有效位,排序版本O(B·n log n)次有界整数工作、O(n)临时空间;Python大整数bit_length/位操作有位成本。选m最小可用heap/selection优化,但不能省略逐项可行成本。

易错点与追问

容易失分的边界

  • 用a|mask直接求最小加法成本。
  • 锁定固定m项后逐位加,错过更优子集。
  • 试位时忽略已保留高位。
  • 抄题目不存在的输入6。

继续深挖

  • 返回最终选择与加法分配怎么重建?
  • m=n能否省排序?
  • 允许减法时该最小成本公式为何失效?
✓已复制微信号!