我在Adnan,Tsung-Hsien和Amit撰写的《编程面试的要素》一书中对问题13.12(第208页)有疑问。
ABC公司需要将工资支出削减到指定目标。 首席执行官想通过限制去年的薪水来做到这一点。每位去年收入超过上限的员工都将在今年获得上限;收入不超过上限的员工将看不到工资的变化。
例如,如果去年有五名雇员的薪水分别为$ 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
教科书解决方案是否已经使用O(1)空间?
答案 0 :(得分:1)
否,这使用python的内置timsort,可以使用O(n)额外的空间,如此处What is the space complexity of the python sort?和What is the space complexity of the python sort?
所述假设您要增加O(1)的空间,则可以替换排序并使用相同的算法。
有几种排序方法,它们不需要额外的空间,不幸的是,大多数排序方法都非常糟糕,平均时间和最坏情况下的时间复杂度为O(n ^ 2)。这是我发现的一个在线列表http://bigocheatsheet.com/?goback=.gde_98713_member_241501229
堆排序不需要额外的空间,时间为O(n log n)。您可以使用python heapq模块轻松实现它。整理列表,然后弹出最少的元素,直到达到阈值为止,基本上与发布的代码示例相同。
我假设您的意思是O(1)额外的空间,因为如果您的意思是总共O(1)的空间,那么我目前没有答案。该函数无法使用列表,因为它将占用O(n)空间。也许您可以使用生成器作为输入来做到这一点,尽管那是作弊的-输入空间可能只是被隐藏了。
答案 1 :(得分:0)
教科书的解决方案是O(n)。最坏的情况是,代码循环通过每个薪水。因此,该解决方案必须执行的步骤数取决于传入的薪水。
此外,正如肯尼(Kenny)在评论中指出的那样,称为排序,这也增加了复杂性。
如果此解决方案为O(1),则无论传入多少薪水,每次解决此问题的步骤数都是相同的。