将数组拆分为四个子数组

时间:2017-03-03 12:04:21

标签: java arrays algorithm

  

给定一个数组,它包含N个元素,它们都是正整数;如果我们能找到三个元素,他们将数组分为四个部分(注意:三个元素不包含在四个的任何部分中),以及每个部分都相等,然后我们将数组称为“平衡”数组。设计一种判断阵列是否平衡的算法,限制为:时间O(N),空间O(N)。

以下是一个例子:

a = [1,7,4,2,6,5,4,2,2,9,8];
b = [1,8,10,5,3,1,2,3]

a是平衡的,因为元素4,5,9将数组划分为[1,7], [2,6], [4,2,2], [8],每个的总和为8。 b不平衡,因为我们无法找到解决方案。

任何想法都表示赞赏!

2 个答案:

答案 0 :(得分:0)

提示

考虑要删除的第一个元素。

一旦知道了这个位置,就可以计算第一部分的大小。

一旦知道第一部分的大小,就可以计算要删除的第二个元素的位置,依此类推(因为所有元素都是正整数)。

现在你需要找到一种在O(N)中执行此操作的方法。试着考虑一下你可以做些什么来重复已经完成的计算,例如通过保持每个零件尺寸的滚动总和。

答案 1 :(得分:0)

您可以尝试使用此解决方案:

class BalancedArray
{

  public static void main( String[] args ) throws java.lang.Exception
  {
    int[] a = {      1, 7, 4, 2, 6, 5, 4, 2, 2, 9, 8   }; //BALANCED
    //int[] a = {7,0,6,1,0,1,1,5,0,1,2,2,2}; //BALANCED
    //int[] a = {1}; //NOT BALANCED
    int l = a.length;
    if ( l < 7 )
    {
      System.out.println( "Array NOT balanced" );
    } else
    {
      int maxX = l - 5;
      int maxY = l - 3;
      int maxZ = l - 1;
      int x = 1;
      int y = 3;
      int z = 5;
      int sumX = 0; //From 0 to x
      int sumY = 0; //From x to y
      int sumJ = 0; //From y to z
      int sumZ = 0; //From z to l

      for(x = 1; x < maxX; x++)
      {                       
        sumX = calcSum(a,0,x);

        for(y = x + 2; y < maxY; y++)
        {         
          sumY = calcSum(a,x+1,y);

          if(sumY != sumX){
            continue;
          }

          for(z = y + 2; z < maxZ; z++)
          {
            sumJ = calcSum(a,y+1,z);

            if(sumJ != sumY)
            {
              continue;
            }

            sumZ = calcSum(a,z+1,l);

            if(sumZ != sumJ){
              continue;
            }

            if(sumZ == sumX && sumX == sumY && sumY == sumJ)
            {
              System.out.println( "Array balanced!!! Elements -> X:" + x + " Y: " + y + " Z:" + z );
              return;
            }

          }
        }
      }

      System.out.println("Array NOT balanced!!");
    }
  }

  private static int calcSum(int[] src, int start, int end)
  {
    int toReturn = 0;
    for ( int i = start; i < end; i++ )
    {
      toReturn += src[i];
    }
    return toReturn;
  }
}

我做了这些假设:

  1. 三个元素中的每一个之间,应该将数组分成4个部分,必须至少有2个距离;
  2. 要分为4个子数组,源数组必须至少7个元素长;