You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于《编程面试要素》13.12题薪资上限算法O(1)空间的疑问

关于《编程面试要素》13.12题薪资上限算法的O(1)空间疑问

先明确问题背景与题目细节:

ABC公司需将薪资总额削减至指定目标值,CEO计划通过设定去年薪资的上限实现:去年薪资超过上限的员工今年按上限发放,未超过的薪资不变。例如,5名员工去年薪资为$90、$30、$100、$40、$20,目标薪资总额为$210时,合适的上限是$60,因60+30+60+40+20=210。需设计算法,根据现有薪资和目标总额计算薪资上限。

课本给出的解决方案代码如下:

def find_salary_cap(target_payroll, current_salaries):
    current_salaries.sort()
    unadjusted_salary_sum = 0.0
    for i, current_salary in enumerate(current_salaries):
        adjusted_people = len(current_salaries) - i
        adjusted_salary_sum = current_salary * adjusted_people
        if unadjusted_salary_sum + adjusted_salary_sum >= target_payroll:
            return (target_payroll - unadjusted_salary_sum) / adjusted_people
        unadjusted_salary_sum += current_salary
    # No solution, since target_payroll > existing payroll.
    return -1.0

你的疑问解答:

1. 课本的解决方案是否已经使用O(1)空间?

答案是不一定,核心取决于排序步骤的空间复杂度:

  • 代码中调用的current_salaries.sort()是Python列表的原地排序方法(基于Timsort实现)。但Timsort在排序过程中需要额外的辅助空间,最坏情况下空间复杂度为O(n)(n为薪资数组长度),所以使用默认排序的话,整个算法的额外空间复杂度达不到O(1)。
  • 这里要注意:「原地排序」不等于「O(1)空间排序」,原地排序仅指不额外开辟与输入同规模的数组存储结果,但仍可能需要一定量的辅助空间。

2. 能否仅用O(1)空间解决该问题?

当然可以,只需要把排序步骤替换为真正的O(1)空间原地排序算法即可:

  • 最优选择是堆排序:堆排序是原地排序算法,额外空间复杂度为O(1)(仅需常数级临时变量),时间复杂度为O(n log n),和Timsort处于同一效率量级。
  • 替换排序步骤后,后续的遍历逻辑和原代码完全一致,整个算法的额外空间就能做到O(1)。
  • 如果不介意时间效率降低(比如面试场景允许),也可以选择冒泡排序、插入排序这类O(1)空间但O(n²)时间的排序算法,但堆排序显然是更优方案。

另外补充:如果题目允许修改输入数组(大多数编程面试场景默认允许,除非明确禁止),用堆排序替换默认的Timsort就能满足O(1)空间要求;如果不允许修改输入,还可以通过迭代实现快速选择来找到分割点,同样能做到O(1)空间,但实现复杂度会更高。

内容的提问来源于stack exchange,提问作者nataman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:56:43