塔楼高度之间的最小差异?

时间:2015-08-26 18:19:15

标签: arrays algorithm data-structures puzzle

我正在接受一些面试问题,我看到了这个问题

你被给予n塔的高度和值k。你必须增加或减少每个塔的高度k。您需要最小化最长和最短塔的高度之间的差异,并输出这个差异。

我认为答案是(maxheight-k) - (minheight + k)。 我试过一些测试用例,它运行正常。

但我不确定,我想我错过了什么,是吗?

8 个答案:

答案 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 。有两种情况:

  • 如果 i << em> n ,则最后最短塔的最终高度为min( h 1 + k h i +1 k )和最后一个最后最高塔的高度为max( h i + k h n - k )。在这种情况下,最终的区别是后者减去前者。
  • 如果 i = n ,那么我们平均增加了所有塔的高度,因此最终的差异只是 h n - h 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,则将iindex的那个set(for循环中的索引k处的值)加set[i]-k >= 0;否则,如果数字为1和set,则k中该索引处的值被k减去(现在您可以反过来添加或减去+k,直到获得所有可能的组合都没有关系-kset[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/

方法:

  • 从数组中查找最大,最小元素。上)。取平均值avg =(max_element + min_element)/ 2。
  • 再次遍历数组,对于每个元素,检查其是否小于avg或更大。
  • 如果当前元素arr [i]小于avg,则将“ k”添加到a [i],即a [i] = a [i] + k。
  • 如果当前元素arr [i]大于或等于avg,则从a [i]中减去k,即a [i] = a [i]-k;
  • 再次从修改后的数组中找出最小和最大元素。
  • 返回min(max1-min1,max2-min2),其中(max1,min1)=修改数组之前初始的max和min元素,而(max2,min2)是修改后的max和min元素。

完整代码可在此处找到:https://ide.geeksforgeeks.org/56qHOM0EOA