数组操作(需要最少删除)

时间:2017-01-07 21:07:26

标签: algorithm

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

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

EX:1 1 1 1 2
答案:1(仅将最后一个元素减少1)。

EX:25 23 1 2
Ans:5(一种可能的方法是减少25到23,减少1到0,减少2到0.在所有减少操作数组之后是23 23 0 0,其中所有非零元素都相等。)

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

2 个答案:

答案 0 :(得分:2)

您的方法很好,但您需要考虑更多目标价值的选择。

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

如果您想加快速度,可以先对条目进行排序。然后,您可以依次轻松计算每个目标值的成本(因为您知道需要将当前位置之前的所有元素减少到0,并将当前位置之后的所有元素减少到目标值,因此总成本是所有元素减去当前值乘以超出当前位置的元素数量

答案 1 :(得分:0)

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

这是算法......

  1. 基本情况:如果数组有负数,则抛出错误或返回-1(错误代码)。
  2. 排序:对数组进行排序 - O(n log n)
  3. 左和:从左到右,每个位置计算左侧所有数字的累计和。 - O(n)
  4. 右和:从右到左,每个位置计算右边所有元素的累计和。 - O(n)
  5. 最小差异:对于每个位置,假设这是您将所有非零元素等同的最小数量。所有较小的数字应减少到零。因此,取左对应此位置的和。所有较大的数字应减少到这个数字。所以,计算多余的东西并将其加到左边的总和上。如果结果总和小于当前最小值,则更新当前最小值。 - O(n)
  6. 整体复杂性为 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;
    }