此面试问题的最佳解决方案

时间:2021-01-26 02:44:24

标签: optimization

谁能提供具有时间复杂度的最佳解决方案?非常感谢!

确定运行预先安排的视频流所需的带宽。
可以有几十万个流,所有的调度数据在开始时都可用。
没有流运行时可能会有时间间隔

输入

=INDEX($C$3:$C$7,MATCH(1,INDEX(COUNTIF(A3,$C$3:$C$7),),0))

输出:

int startTime; //start time for the stream  
int duration; //how long the stream runs  
int bandwidth; // consumed bandwidth from start to end

示例
输入(列表可能未排序)

list[int] totalBW; // bandwidth needed at every time instant

输出

[ [0,2,10], [1,2,10], [2,1,20] ] 

说明

[10, 20, 30]

使用 python 的蛮力方法:

At time 0: only the first element needs bandwidth 10 =>  [10, ...]
At time 1: first two elements need bandwidth 10 + 10 => [10, 20, ...]
At time 2: the second and third element need bandwidth 10 + 20 => [10, 20, 30]

有没有更有效的方法?

1 个答案:

答案 0 :(得分:1)

<块引用>

有没有更有效的方法?

是的。

第一步是将原始数据转换为一组“时间 = T,带宽变化 N”的事件,按时间顺序排序,并通过合并同时发生的事件进行简化。

对于您的示例,如果输入是 [ [0,2,10], [1,2,10], [2,1,20] ] ,那么它将被分解为:

** [ [0,2,10] **
    At 0, bandwidth += 10 
    At 2, bandwidth += -10

** [1,2,10] **
    At 1, bandwidth += 10
    At 3, bandwidth += -10

** [2,1,20] **
    At 2, bandwidth += 20
    At 3, bandwidth += -20

..then 排序和简化(合并同时发生的事件 - 例如 bandwidth += -10, bandwidth += 20 变成单个 bandwidth += 10)得到:

At 0, bandwidth += 10 
At 1, bandwidth += 10
At 2, bandwidth += 10
At 3, bandwidth += -30

从那里开始从排序列表生成最终数组是一个简单的事情:

 10, 20, 30, 0

要理解为什么这更有效,请想象一下如果以更高的精度跟踪时间(例如可能是毫秒而不是秒)并且输入是 [ [0,2000,10], [1000,2000,10], [2000,1000,20] ] 会发生什么。对于我的方法,生成最终数组将成为一个具有 4 次迭代的外循环和一个可以是高度优化的 memset() (C) 或 rep stosd (80x86 程序集) 或 np.full() ( Python 与 NumPy);对于您的方法,外循环需要 30000 次迭代,其中内循环浪费大量时间重复线性搜索(对于外循环的大多数迭代)找到与外循环的前一次迭代相同的答案。

相关问题