SDE · OA Coding

Amazon OA:全局替换数值,让每种值只占一个连续块

把同值首末区间的重叠闭包转为最细分段,最少操作等于不同值数减区间分量数。

题目重点:把同值首末区间的重叠闭包转为最细分段,最少操作等于不同值数减区间分量数。

题意与假设

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

  • 替换是全局、可选任意不同目标值,每次成本1;不是只改一个位置或移动元素。
  • 元素可hash,空输入0;没有保留特定值或限定可替换方向。

解题路线

  1. 每值v的first..last范围必须在最终同一值块内,因为全局替换永不把原v拆到多个final value。两个原值区间重叠就不能成为两个不同连续块,必须最终合并。
  2. 这种约束有传递性:区间重叠图每连通分量的c种值至少要合成一个值。一次替换最多减少一个不同值类,因此至少c-1操作;所有分量相加下界U-C。
  3. 扫描last positions维护当前right=max(last[value]),到i==right才能封口一个分量,类似Partition Labels。分段内没有值跨界,每段恰是区间重叠闭包。
  4. 每段选一个已有值作为目标,把段内其他c-1值全局替换成它;这些值不出段,不破坏其他段,得到一连续块并达到下界。无需模拟每次替换全数组。
  5. 如果允许单点改值、元素交换或指定目标限制,该公式不再自动成立;输入原题这里明确全局替换所以保留合并单调性。

手动走一遍

训练[A,B,A,C,B,D,D]前五项形成A/B/C一个闭包、D独立,U=4,C=2,答案2;可把B与C都换A得到五个A接两个D。A,A,B,C,C无需任何操作。

Python 参考实现

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

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

def minimum_global_replacements(values):
    """One operation replaces every occurrence of one value by another value."""
    last={value:i for i,value in enumerate(values)}
    components=0
    right=-1
    for i,value in enumerate(values):
        right=max(right,last[value])
        if i==right:components+=1
    return len(last)-components

复杂度

O(n)期望时间、O(U)last表;输出具体操作需记录每段不同值并产生U-C个动作,实际逐次修改数组可更慢但并非计算最少次数所需。

易错点与追问

容易失分的边界

  • 把全局替换误当单点编辑。
  • 只数相邻值变化。
  • 两个跨界值不合并闭包。

继续深挖

  • 限制目标值集合时怎样改下界与构造?
  • 要输出替换序列如何选择每段目标?
  • 一个新值是否能降低次数?
✓已复制微信号!