【问题标题】:MinAbsSum: Given array of integers, find the lowest absolute sum of elements [closed]MinAbsSum:给定整数数组,找到元素的最低绝对和 [关闭]
【发布时间】:2019-08-23 06:18:33
【问题描述】:

我在 Codility 中遇到了一个我想解决的问题,并且还收集了该问题的解决方案。问题如下,

对于给定的由 N 个整数组成的数组 A 和由 N 个整数组成的序列 S 集合 {−1, 1},我们定义 val(A, S) 如下:

val(A, S) = |sum{ A[i]*S[i] for i = 0..N−1 }|

(假设零元素之和为零。)

对于给定的数组 A,我们正在寻找这样一个序列 S 最小化 val(A,S)。

写一个函数:

类解决方案 { public int solution(int[] A); }

给定一个包含 N 个整数的数组 A,计算 val(A,S) 来自所有可能的 val(A,S) 值 来自集合 {−1, 1} 的 N 个整数的序列 S。

例如,给定数组:

A[0] = 1 A[1] = 5 A[2] = 2 A[3] = -2 你的函数应该 返回 0,因为对于 S = [−1, 1, −1, 1],val(A, S) = 0,即 最小可能值。

为以下假设编写一个有效的算法:

N 是 [0..20,000] 范围内的整数;数组 A 的每个元素 是 [−100..100] 范围内的整数。

我有下面的解决方案,

public static int solution(int[] A) {

    int N = A.length;

    if (N == 0) {
        return 0;
    }

    int sum = 0;
    int max = Integer.MIN_VALUE;

    for (int i = 0; i < N; i++) {

        int value = Math.abs(A[i]);
        sum += value;

        if (max < value) {
            max = value;
        }

        A[i] = value;
    }


    // A      = [1, 5, 2, -2]
    // A(abs) = [1, 5, 2, 2]

    // Max value = 5
    // Sum value = 10

    // counts  = [0, 1, 2, 0, 0, 1]
    int[] counts = new int[max + 1];

    for (int value : A) {
        counts[value]++;
    }

    // Total = [0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
    int[] Total = new int[sum + 1];

    for (int i = 1; i < Total.length; i++) {
        Total[i] = -1;
    }

    for (int i = 1; i < counts.length; i++) {

        for (int j = 0; j < Total.length; j++) {

            if (Total[j] >= 0) {
                Total[j] = counts[i];
            } else if (j - i >= 0 && Total[j - i] > 0) {
                Total[j] = Total[j - i] - 1;
            }
        }
    }

    int result = sum;

    for (int i = 0; i < Total.length / 2 + 1; i++) {

        if (Total[i] >= 0 && result > Math.abs(sum - 2 * i)) {
            result = Math.abs(sum - 2 * i);
        }
    }

    return result;
}

任何具有良好算法技能的人都可以向我解释解决方案吗?

【问题讨论】:

    标签: java arrays algorithm for-loop math


    【解决方案1】:

    它一个一个地遍历数组的元素。由于我们要添加连续的数字,我们需要做的就是确保总和不会变小。这就是我们取一个数字并检查总和如何变化的原因。

    形式上我们可以这样写:

    max(solution([a1, a2, ..., an]) = sum(abs(a1), abs(a2), ..., abs(an)), 
    

    其中abs 表示绝对值 (|x| = x * signum(x))。

    例子:

    假设我们有一个数组 [1, -2, 3]。绝对值数组将是 [1, 2, 3]。我们需要从所有组合中找出最大值:

    1 + 2 + 3
    1 + 2 - 3
    1 - 2 + 3
    ...
    -1 - 2 - 3
    

    显然因为每个元素前的符号不影响求和,所以我们需要考虑sum + elementsum - element是否更大。最大的是绝对值之和:1 + 2 + 3

    【讨论】:

    • 我们需要找到最小和,而不是最大...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 2022-12-12
    • 2012-11-10
    • 2022-11-16
    • 2020-11-02
    相关资源
    最近更新 更多