这是我在校园实习中向我询问的面试问题之一。
有'n'个服务器分配了一些负载(整数)。我们必须找出分钟。平衡它们所需的时间,使每个服务器上都有负载1。
每个服务器只能与其相邻的邻居(左侧和右侧)共享其负载。
所有服务器上的总负载加起来为n。
实施例。
n = 10
最初,0,0,10,0,0,0,0,0,0,0
时间1:0,1,8,1,0,0,0,0,0,0
时间2:1,1,6,1,1,0,0,0,0,0
。
。
时间7:1,1,1,1,1,1,1,1,1,1
答案是7。
最初,服务器上的负载可以以任何方式存在。没有必要它只会出现在我们当前示例中的一台服务器上。
我该如何解决?我无法想出任何方法。
提前致谢
答案 0 :(得分:3)
对于每台服务器,您需要确定需要向左移动多少负载以及需要向右移动多少。在您的示例中,只有两个作业可以向左移动,因此7个必须向右移动,这需要7个时间段。
如果你有这样的情况
0, 0, 6, 0, 4, 0, 0, 0, 0, 0
然后只有两个可以从6向左移动,所以三个需要向右移动。占据前六个服务器,因此4个作业需要占用最后四个服务器。因此需要5个时间段,因为一个作业需要从4移动到最后一个服务器。
另一个例子,n = 15
0, 0, 0, 3, 0, 0, 0, 0, 4, 0, 0, 6, 2, 0, 0
3需要向左移动,需要3个时间段。 4需要向左移动,需要5个时间段(因为其中一个工作必须占用3个空出的空间)。 6个中的4个工作需要向左移动,需要4个时间段。其中一项工作需要向右移动,需要一段时间。这2个工作需要向右移动,需要2个时间段。答案是5,因为4中的一个工作需要向左移动5个位置。
从这些示例中可以清楚地看出,问题的解决方案是 O(n)解决方案:
int excess = 0;
int answer = 0;
for ( int i = 0; i < N; i++ )
{
excess = excess + array[i] - 1;
if ( abs(excess) > answer )
answer = abs(excess);
}
当工作需要向左移动时,excess
为负,而当工作需要向右移动时,excess
为正。 answer
的绝对值的最大值为GetAllConferences()
。
答案 1 :(得分:3)
我假设负载总和不超过服务器数量。我的方法是随着时间的推移使用二进制搜索,复杂度为 O(n * logn)。
说,我要检查是否可以及时平衡负载 t 。而且我更愿意先将服务器 s 的负载分配给它们的左侧。如果无法将所有负载分配到左侧(因为可能需要超过时间 t 将所有负载分配到左侧或者这些服务器中的一些已经被占用),那么我我要选择右侧的服务器。如果可以在 t 的时间内分配所有负载,那么我将在下一次迭代中选择较小的 t ,否则更高(也称为二进制搜索)。 / p>
bool isBalancableWithin(Time t, Load[] loads) {
int lastOccupiedIndex = -1;
foreach (index, loads) {
int startIndex = max(lastOccupiedIndex + 1, index - t);
int endIndex = startIndex + loads[i] - 1;
if (endIndex > index + t || endIndex >= loads.length) return false;
lastOccupiedIndex = endIndex;
}
return true;
}
Time lowerBound(Load[] loads) {
Time lowest = 0;
Time highest = loads.length;
while (lowest <= highest) {
Time mid = (lowest + highest) / 2;
if (isBalancableWithin(mid, loads)) highest = mid - 1;
else lowest = mid + 1;
}
return lowest;
}