我在面试中遇到了这样一个问题:

一个地区有工厂生产污染性气体,每个工厂都要安装过滤器以减少污染.安装的每个过滤器将使那家工厂的污染减少一半.每个工厂可以有多个过滤器.有一个N个整数的列表,代表该地区N家工厂的污染水平.找出减少一半总污染所需的最小过滤器数量.

例如,[3,5,6,1,18]是5家工厂的污染水平列表

  • 总体污染=3+5+6+1+18=33(目标为33/2=16.5)

  • 在索引=4的工厂安装过滤器-->污染水平将为[3,5,6,1,9]

  • 在索引=4的工厂安装过滤器-->污染水平将为[3,5,6,1,4.5]

  • 在索引=2的工厂安装过滤器-->污染水平将为[3,5,3,1,4.5]

  • 至少需要3个过滤器,达到总污染的一半.

N是[1…30000]范围内的整数.列表中的每个元素都是[0…70000]范围内的整数

我想出的解决方案很简单:

def solution(A):
    total = sum(A)
    target = total/2
    count = 0
    while total>target:
        count+=1
        max_p = max(A)
        total-= max_p/2
        A.remove(max_p)
        A.append(max_p/2)
    return count

除了时间复杂度似乎为O(N^2)之外,这一方法效果良好.有人能提出一种时间复杂度较低(最好是O(N))的解决方法吗?

推荐答案

也许你可以利用max heap比现在更有效地检索最差的工厂,也就是说,使用堆可以实现O(N log N)解决方案:

import heapq


def filters_required(factories: list[int]) -> int:
    """Returns minimum filters required to halve pollution."""
    current_pollution = sum(factories)
    goal_pollution = current_pollution / 2
    filters = 0
    factory_pollution_max_heap = [-p for p in factories]
    heapq.heapify(factory_pollution_max_heap)
    while current_pollution > goal_pollution:
        worst_factory = heapq.heappop(factory_pollution_max_heap)
        pollution = worst_factory / 2
        current_pollution += pollution  # Use += since pollution will be a negative number.
        heapq.heappush(factory_pollution_max_heap, pollution)
        print('DEBUG:', [-p for p in factory_pollution_max_heap], current_pollution)
        filters += 1
    return filters


def main() -> None:
    print(f'{filters_required(factories=[3, 5, 6, 1, 18]) = }')


if __name__ == '__main__':
    main()

Output:

DEBUG: [9.0, 6, 3, 1, 5] 24.0
DEBUG: [6, 5, 3, 1, 4.5] 19.5
DEBUG: [5, 4.5, 3, 1, 3.0] 16.5
filters_required(factories=[3, 5, 6, 1, 18]) = 3

Python相关问答推荐

在Python中对分层父/子列表进行排序

根据条件将新值添加到下面的行或下面新创建的行中

如何使用pandasDataFrames和scipy高度优化相关性计算

抓取rotowire MLB球员新闻并使用Python形成表格

log 1 p numpy的意外行为

两个pandas的平均值按元素的结果串接元素.为什么?

OR—Tools CP SAT条件约束

Polars asof在下一个可用日期加入

在极中解析带有数字和SI前缀的字符串

处理具有多个独立头的CSV文件

Odoo16:模板中使用的docs变量在哪里定义?

根据Pandas中带条件的两个列的值创建新列

freq = inject在pandas中做了什么?''它与freq = D有什么不同?''

Python将一个列值分割成多个列,并保持其余列相同

每次查询的流通股数量

如何写一个polars birame到DuckDB

用来自另一个数据框的列特定标量划分Polars数据框中的每一列,

对于数组中的所有元素,Pandas SELECT行都具有值

查找数据帧的给定列中是否存在特定值

Scipy.linprog的可行性有问题吗?(A_ub@x0<;=b_ub).all()为True-但是-linprog(np.zeros_like(X0),A_ub=A_ub,b_ub=b_ub)不可行