我正在接受一些面试问题,我看到了这个问题
你被给予n塔的高度和值k。你必须增加或减少每个塔的高度k。您需要最小化最长和最短塔的高度之间的差异,并输出这个差异。
我认为答案是(maxheight-k) - (minheight + k)
。
我试过一些测试用例,它运行正常。
但我不确定,我想我错过了什么,是吗?
答案 0 :(得分:5)
m7thon的答案说明了您的解决方案所存在的问题,因此,我仅说明您如何实际解决此问题。 。
要观察的主要事情是,对于任何给定的塔,如果您选择将其高度从 h i 增至 h i + k ,那么您也可以增加所有较短塔的高度:这不会影响最大塔数(因为如果 h j << em> h i ,然后是 h j + k <<< em> h i + k ),而 可能会增加最小值。相反,如果您选择将塔的高度从 h i 降低到 h em> i − k ,那么您最好降低所有较高塔的高度。
因此,虽然有2 n 种可能的方法来选择应该增加还是减少的塔楼,我们实际上可以忽略其中的大多数。一些塔将成为我们增加高度的最高塔;对于所有较短的塔,我们也将增加它们的高度,对于所有较高的塔,我们将降低它们的高度。因此,只有 n 有趣的方法来选择应该增加还是减少的塔楼:每座塔楼成为我们增加高度的最高塔楼的机会之一。 / p>
[脚注1:您可能会注意到,降低所有塔的高度也是有效的,在这种情况下,没有这样的塔。但这等同于增加所有塔楼的高度-无论我们向每个高度添加 k 还是从每个高度减去 k ,无论哪种方式,并没有实际更改max-min-min。]
[脚注2:我只提到了“较短的塔”和“塔高塔”,但也有可能多个塔具有相同的初始高度。但是这种情况并不是很重要,因为我们可能会全部增加或减少全部-没有必要增加一些或减少一些。因此,这里描述的方法仍然可以正常工作。]
因此,让我们从对原始高度进行排序并按升序编号开始,这样 h 1 是原始最短塔和的原始高度> h n 是最初最高的塔的原始高度。
对于每个 i ,尝试以下可能性:最短的 i 塔是我们增加高度的最高塔;也就是说,尝试通过 h i 增加 h 1 的可能性,然后通过 h n 减少 h i +1 。有两种情况:
然后,我们将所有这些可能性中的 n 差异最小。
这是一个实现此高度的Java方法(假设高度为int
;注意 h i 为{{1 }}和 h i +1 是arr[i-1]
):
arr[i]
请注意,为方便起见,我在循环之前拉了 i == n 案例。
答案 1 :(得分:2)
我猜这来自 gfg。
@ruakh 的答案可能是我在网上找到的最好的答案,它适用于大多数情况,但是对于 gfg 上的练习问题,有一些情况会导致最小值低于 0,并且问题不允许任何高度 < 0。
因此,您需要进行额外检查,其余部分几乎完全受 ruakh 的回答启发
class Solution {
int getMinDiff(int[] arr, int n, int k) {
Arrays.sort(arr);
int ans = arr[n-1] - arr[0];
int smallest = arr[0] + k, largest = arr[n-1]-k;
for(int i = 0; i < n-1; i++){
int min = Math.min(smallest, arr[i+1]-k);
int max = Math.max(largest, arr[i]+k);
if(min < 0) continue;
ans = Math.min(ans, max-min);
}
return ans;
}
}
我还对高度进行了基于 0 的索引以使其更加明显,但这可能是主观的。
编辑:< 0 检查很重要的一种情况是数组是
8 1 5 4 7 5 7 9 4 6
和 k 是 5。这个的预期答案是 8,如果没有 < 0 检查,你会得到 7。
答案 2 :(得分:1)
首先,你需要找到塔的平均高度。 让我们说高度分别是3,7,17,25,45和k = 5 平均值=(3 + 7 + 17 + 25 + 45)/ 5 = 97/5 = 19.4
现在我们将尝试使每个建筑物更接近平均高度。
对于3高塔,我们必须增加5次,使得高度= 3 +(3 * 5)= 18(18比23更接近)接近平均值。
对于7个高度我们将增加5次= 7 +(2 * 5)= 17(17比22更接近)
同样25将变为25 - 5 = 20 45将变为45 - (5 * 5)= 20
你的身高将变为18,17,17,20,20
答案 3 :(得分:0)
让我们说你有三座高塔1,4和7,k = 3.根据你的推理,最佳最小差异是(7 - 3) - (1 + 3)= 0.但是你做什么与塔高4?您需要增加或减少此值,因此在此示例中,您可以实现的最小差异实际为3。
即使你被允许将塔保持在它的高度,那么例子1,5,7也会反驳你的假设。
我知道这并不能解决实际的最小化问题,但它确实表明它并不像你想象的那么简单。我希望这能回答你的问题“我错过了什么吗?”。
答案 4 :(得分:0)
这里有点晚。这些家伙已经向您解释了问题并提供了解决方案。但是,我自己准备了此代码。我准备的代码不是您应该遵循的最佳代码,但是清楚地了解了使用蛮力可以做到这一点的方法。
set = list(map(int, input().split()))
k = int(input())
min = 999999999
for index in range(2**len(set)):
binary = [] //probably should have used integer to binary fuction here
while index != 0:
remainder = index % 2
index //= 2
binary.append(remainder)
while len(binary) != len(set):
binary.append(0)
binary.reverse()
separateset = []
flag = 0
for i in range(len(binary)):
if binary[i] == 0:
separateset.append(set[i]+k)
elif binary[i] == 1 and set[i]-k >= 0:
separateset.append(set[i]-k)
else:
flag = 1
break
if flag == 0:
separateset.sort()
if min > separateset[-1] - separateset[0]:
min = separateset[-1] - separateset[0]
print(min)
这是通过识别set
变量的所有可能子集而进行的,只是进行了一些修改。如果数字为0,则将i
与index
的那个set
(for循环中的索引k
处的值)加set[i]-k >= 0
;否则,如果数字为1和set
,则k
中该索引处的值被k减去(现在您可以反过来添加或减去+k
,直到获得所有可能的组合都没有关系-k
和set[i]-k >= 0
中的一个)。遵循flag
是因为负高度是没有意义的,并且如果发生这种情况,separatesort
将变为1并中断。但是,如果标志为0,则表示所有高度均为正,然后min
被排序,然后min
存储最大塔和最短塔之间的差。最终,ContentContentProvider.applyBatch()
的差异最小。
答案 5 :(得分:0)
第一步:
<块引用>将所有高度减少 'k' 并按非递减顺序对其进行排序。
第 2 步:
<块引用>我们需要将一些高度子集增加 '2 * k'(因为它们减少了 'k' 在 step1 中,因此,为了有效地将它们的高度增加 'k' 我们需要 添加“2*k”)。
第 3 步:
<块引用>显然,如果我们增加第 i 个高度而不增加 'i-1'th 那么,它不会有用,因为最小值仍然相同 并且最大值也可能增加!
第 4 步:
<块引用>考虑在前缀的每个元素中添加了'2*k'的所有前缀。 然后计算并更新 (max - min) 值。
答案 6 :(得分:0)
让我知道我在这里错过了哪个场景,
class Solution:
def getMinDiff(self, arr, n, k):
for i in range(n):
if arr[i] < k: arr[i] += k
else: arr[i] -= k
result = max(arr) - min(arr)
print('NewArr: {}\nresult: {}'.format(arr, result))
return result
答案 7 :(得分:-1)
此方法适用于GfG练习,问题链接:https://practice.geeksforgeeks.org/problems/minimize-the-heights/0/
方法:
完整代码可在此处找到:https://ide.geeksforgeeks.org/56qHOM0EOA