Algorithm 数组操作(所需的最小删除数)

Algorithm 数组操作(所需的最小删除数),algorithm,Algorithm,给定一个正整数数组,我可以将任何元素减少任意数量,以使所有剩余的非零元素相等 我必须找到最小值,它是所有下降的总和 例:12 Ans:1(仅将最后一个元素减少1) 例:252312 Ans:5(一种可能的方法是将25减少到23,将1减少到0,将2减少到0。在所有减少操作之后,数组是23 23 0 0,所有非零元素都相等。) 我尝试了在数组中找到最小值,然后将所有其他元素与之相等的方法。但是这种方法在第二种情况下失败了。对此的任何帮助都是高度赞赏的。 你的方法是好的,但是你需要考虑更多的目标值选择

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

我必须找到最小值,它是所有下降的总和

例:12
Ans:1(仅将最后一个元素减少1)

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


我尝试了在数组中找到最小值,然后将所有其他元素与之相等的方法。但是这种方法在第二种情况下失败了。对此的任何帮助都是高度赞赏的。

你的方法是好的,但是你需要考虑更多的目标值选择。

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


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

你的方法听起来不错,但有很大的缺陷,而且并不总是奏效。如果没有将数字等于零的选项,这将是可行的。在这个问题场景中,对于每个候选对象,您应该通过将所有较大的数字与该候选对象相等,将所有较小的数字等于零来计算差异之和,并查看哪个候选对象的差异之和最小

这是算法

  • 基本情况:如果数组有负数,则抛出错误或返回-1(错误代码)
  • 排序:对数组进行排序-O(n log n)
  • 左和:从左到右,为每个位置计算左侧所有数字的累积和。-O(n)
  • 右和:从右到左,为每个位置计算右侧所有元素的累积和。-O(n)
  • 最小差异:对于每个位置,假设这是将所有非零元素相等的最小数量。所有较小的数字都应减为零。所以,取这个位置对应的左和。所有较大的数字都应减少到该数字。因此,计算多余的部分,并将其添加到左和中。如果结果和小于当前最小值,则更新当前最小值。-O(n)
  • 总体复杂性是O(n logn),下面是一些代码

    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;
    }
    
    private static int getMinimumDifference(int[]arr){
    int n=阵列长度;
    对于(int i=0;i=0;i--){
    右[i]=tempSum;
    tempSum+=arr[i];
    }
    int minDiff=tempSum,index=-1;
    对于(int i=0;i=0?arr[index]:“未知”);
    返回minDiff;
    }
    
    第一个示例的答案不应该是1,因为您必须将最后一个元素(2)减少1,以使“所有剩余的非零元素……相等”(1)?或者任何元素都必须为零?@Reinhardmanner是的,对不起……输入错误。只是补充一下:“您可以先对条目排序”。。。对于O(n logn)的总复杂度,排序和所有二进制搜索都需要找到哪些元素将变为零,哪些将成为目标值。