【问题标题】:Array manipulation (Minimum deletions required)数组操作(需要最少删除)
【发布时间】:2017-01-07 21:07:26
【问题描述】:

给定一个正整数数组,我可以将任何元素减少任意数量,使得所有剩余的非零元素都相等。

我必须找到最小值,它是所有减少的总和。

例如:1 1 1 1 2
Ans: 1(仅将最后一个元素减 1)。

例如:25 23 1 2
Ans: 5 (一种可能的方法是将 25 减少到 23,将 1 减少到 0,将 2 减少到 0 。毕竟减少操作数组是 23 23 0 0 ,其中所有非零元素都相等。)

我尝试了在数组中找到最小值然后将所有其他元素等同于该最小值的方法。但是这种方法在第二种情况下失败了。对此的任何帮助都非常感谢。

【问题讨论】:

  • 第一个示例的答案不应该是 1,因为您必须将最后一个元素 (2) 减少 1 以使“所有剩余的非零元素......相等”(1)?还是要求任何元素都为零?
  • @ReinhardMänner 是的,抱歉...打字错误。

标签: algorithm


【解决方案1】:

您的方法不错,但您需要为目标值考虑更多选择。

它可以是数组中的任何值,因此只需依次尝试所有值。这将是一个 O(n^2) 算法。

如果你想走得更快,你可以先对条目进行排序。然后你就可以很容易的依次计算出每个目标值的代价(因为你知道你需要把当前位置之前的所有元素都减到0,把当前位置之后的所有元素都减到目标值,所以总代价就是所有元素减去当前值乘以当前位置以外的元素个数)

【讨论】:

  • 只是补充:“你可以先对条目进行排序”......对于 O(n log n) 的总复杂度,无论是排序还是查找哪些元素所需的所有二进制搜索变成零,这将成为目标值。
【解决方案2】:

您的方法听起来不错,但存在重大缺陷,而且并非始终有效。如果没有将数字等同于零的选项,它将起作用。在这个问题场景中,对于每个候选者,您应该计算通过将所有较大的数字等同于该候选者并将所有较小的数字等同于零而获得的差异之和,并查看哪个候选者的差异之和最小。

这是算法...

  1. 基本情况:如果数组有负数,则抛出错误或返回 -1(错误代码)。
  2. 排序: 对数组进行排序 - O(n log n)
  3. Left Sum:从左到右,为每个位置计算左侧所有数字的累积和。 - O(n)
  4. Right Sum:从右到左,为每个位置计算右侧所有元素的累积和。 - O(n)
  5. 最小差异:对于每个位置,假设这是您将所有非零元素等同于的最小数量。所有较小的数字都应减少到零。所以,取这个位置对应的左和。所有较大的数字都应该减少到这个数字。因此,计算什么是多余的并将其添加到左侧总和中。如果结果总和小于当前最小值,则更新当前最小值。 - O(n)

总体复杂度为 O(n log n),下面是一些代码...

private static int getMinimumDifference(int[] arr) {
    int n = arr.length;

    for (int i = 0; i < n; i++) {
        if (arr[i] < 0) {
            return -1;
        }
    }
    if (n == 1)
        return 0;

    int left[] = new int[n];
    int right[] = new int[n];

    Arrays.sort(arr);

    int tempSum = 0;
    for (int i = 0; i < n; i++) {
        left[i] = tempSum;
        tempSum += arr[i];
    }

    tempSum = 0;
    for (int i = n - 1; i >= 0; i--) {
        right[i] = tempSum;
        tempSum += arr[i];
    }

    int minDiff = tempSum, index = -1;
    for (int i = 0; i < n; i++) {
        int diff = 0;
        diff += left[i]; // All numbers on the left reduced to 0
        diff += right[i] - (arr[i] * (n - i - 1)); // All numbers on the right reduced to arr[i]
        if (diff < minDiff) {
            minDiff = diff;
            index = i;
        }
    }
    System.out.println("Minimum difference is " + minDiff + " and all numbers should be " + (index >= 0 ? arr[index] : "unknown"));
    return minDiff;
}

【讨论】:

    猜你喜欢
    • 2020-02-12
    • 1970-01-01
    • 2016-07-20
    • 2016-12-03
    • 1970-01-01
    • 2014-02-25
    • 2017-08-29
    • 1970-01-01
    相关资源
    最近更新 更多