古城里有n座不同楼层的塔楼。我们必须在它们上面建造地板,使得n个塔中的至少m个(n> = m)具有相同的高度。编写一个函数来计算需要为m个楼层构建的最小楼层数量。
示例:给定一个数组(1,5,4,2,1),每个元素代表该塔中的楼层数,m = 3,该函数应返回2,因为我们必须在塔上建立1层楼指数0& 4所以3座塔的高度相等。下面的函数定义
public Integer calcMinFloors(Integer[] towers, int m);
答案 0 :(得分:3)
从@ gnasher729更新答案:
n
元素数组的简单解决方案:
(5,4,2,1,1)
m-1
下一个元素。总结差异并保存最小值。时间复杂度O(n*m)
稍微更先进的解决方案:
(5,4,2,1,1)
(5)
,向前看m-1
个元素(4,2)
,计算您需要的楼层数(1 + 3 = 4)
,并将结果保存为best
和{ {1}} current
,计算值:i
。保存到current = current - (arr[i-1] - arr[i])*(m-1) + arr[i]-arr[i+m-1]
,如果它小于它。 对于步骤2-3,这应该为排序+ best
提供时间复杂度O(n*log(n))
。
答案 1 :(得分:2)
此问题可解决的是时间 O(NlogN)和恒定空间 O(1),其中 N 是塔的数量。
我们必须制作相同高度的m
塔,这样我们才能建造最小楼层。
重要观察
<强> 1 即可。因为我们正在建造最小的楼层,而不是在m
塔上建造楼层并达到相同的高度,我们将尝试使m - 1
塔与目标塔的高度相等。
<强> 2 即可。最佳解决方案是找到具有最小高度差的总和的m
塔。让解决方案是具有升序的以下楼层的塔:
m1 , m2 , m3 , ....... m floor
最佳解决方案具有以下属性:
差异的总和最小:
(m - m1) + (m - m2) + (m - m3) + .....(m - (m-1))
因为只有这样我们才能说我们需要建立最少的楼层数。
所以事实证明我们需要找到一组m个楼层,这样他们的高度与地面的最大高度(在那些m塔内)的差异是最小的。
假设我们有长度为n的数组arr
,描绘了每个塔楼的楼层数。首先我们sort
塔的高度。
然后我们开始以下列方式找到differences
的总和。我们在index i
处。我们找到以下总和:
arr[i + m - 1] - arr[i]
+
arr[i + m - 2] - arr[i]
+
arr[i + m - 3] - arr[i]
+
arr[i + m - 4] - arr[i]
.
.
.
arr[i + 1] - arr[i]
让我们调用总和s1
。现在,当我们考虑下一组m
塔时,意为从索引i + 1
到i + m
,的塔,我们不需要循环来计算差异的总和,它可以简单地来自以下:
(m - 1)*arr[i + m] - s1 - ((m-1)*arr[i])
因此,使用这种简单的数学技术,我们只需要一个for循环来解决这个问题。
提出的算法的伪代码是:
Sort the array arr of n towers.
Compute the sum of differences for first set of m towers.
sum = 0
for(i = 1 to m - 1)
{
sum = sum + arr[i] - arr[0]
}
Now for the remaining set of m towers
previous_sum = sum, sum = 0, j = 1
minimum_sum = previous_sum
for(i = m to n - 1)
{
sum = (m-1)*arr[i] - previous_sum - (m - 1)*arr[j - 1]
increment j
if( sum < minimum_sum )
{
minimum_sum = sum
}
previous_sum = sum
}
The answer is minimum_sum.
答案 2 :(得分:0)
您按高度按升序或降序排序,其余的则是微不足道的。