【问题标题】:Partitioning an array into 3 sets将数组分成 3 组
【发布时间】:2015-02-25 23:00:10
【问题描述】:

给定一个整数数组,将数组分成 3 个集合,使 3 个集合的元素之和尽可能接近。

我的方法如下:

  1. 按降序对数组进行排序
  2. 将元素插入总和最小的集合中。


sort(a, a+n);
int o = 0, tw = 0, th = 0;

while(n--)
{
  if (o <= tw && o <= th)
    o += a[n];
  else if (tw <= o && tw <= th)
    tw += a[n];
  else 
    th += a[n];
}

谁能告诉我我的解决方案有什么问题?或者可以建议更好的解决方案

【问题讨论】:

  • 您的算法将如何处理负数?
  • 是什么让您认为您的解决方案有问题?或者,就此而言,是什么让您认为这是一个很好的解决方案?
  • 我没有得到想要的输出,而且我首先想要正整数的算法。
  • @MonelGupta,试着解释一下“期望的输出”到底是什么。请提供输入和(不需要的)输出。
  • 数组是[3,4,1,3]第一组是{3},第二组是{3,1},第三组是{4}。

标签: algorithm divide-and-conquer subset-sum arrays


【解决方案1】:

这里是你可以使用的蛮力 java 解决方案,注意 - 这个解决方案的复杂度是 O(3^N),非常慢

/**
 * Returns absolute difference between 3 values in array
 */
static int getdiff(final int s[])
{
    return Math.abs(s[0] - s[1]) + Math.abs(s[1] - s[2]) + Math.abs(s[2] - s[0]);
}

/**
 * Calculates all possible sums and returns one where difference is minimal
 */
static int[] getsums(final int a[], final int idx, final int[] s)
{
    // no elements can be added to array, return original
    if (idx >= a.length)
        return s;

    // calculate 3 different outcomes
    final int[] s1 = getsums(a, idx + 1, new int[] {s[0] + a[idx], s[1], s[2]});
    final int[] s2 = getsums(a, idx + 1, new int[] {s[0], s[1] + a[idx], s[2]});
    final int[] s3 = getsums(a, idx + 1, new int[] {s[0], s[1], s[2] + a[idx]});

    // calculate difference
    final int d1 = getdiff(s1);
    final int d2 = getdiff(s2);
    final int d3 = getdiff(s3);

    if ((d1 <= d2) && (d1 <= d3))
        return s1;
    else if ((d2 <= d1) && (d2 <= d3))
        return s2;
    else
        return s3;
}

static int[] getsums(final int a[])
{
    return getsums(a, 0, new int[] {0, 0, 0});
}

static void printa(final int a[])
{
    System.out.print("[");
    for (final int t : a)
        System.out.print(t + ",");
    System.out.println("]");
}

static public void main(final String[] args)
{
    final int a[] = new int[] {23, 6, 57, 35, 33, 15, 26, 12, 9, 61, 42, 27};

    final int[] c = getsums(a);

    printa(a);
    printa(c);
}

样本输出:

[23,6,57,35,33,15,26,12,9,61,42,27,]
[115,116,115,]

【讨论】:

猜你喜欢
  • 2012-01-31
  • 2018-11-17
  • 1970-01-01
  • 2017-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多