查找最大和子数组的开始和结束索引

时间:2019-04-20 16:41:36

标签: java arrays data-structures logic

我有一个分配,需要找到最大和子数组。
我用Google搜索了很多解决方案,但是每个解决方案只返回最大子数组的总和。
我的要求是在数组中找到sum +该和的开始和结束索引。
代码:-

class MaxSubarray {

  // function to return maximum number among three numbers
  static int maximum(int a, int b, int c)
  {
    if (a>=b && a>=c)
      return a;
    else if (b>=a && b>=c)
      return b;
    return c;
  }

  // function to find maximum sum of subarray crossing the middle element
  static int maxCrossingSubarray(int ar[], int low, int mid, int high)
  {
    /*
      Initial leftSum should be -infinity.
    */
    int leftSum = Integer.MIN_VALUE;
    int sum = 0;
    int i;

    /*
      iterating from middle
      element to the lowest element
      to find the maximum sum of the left
      subarray containing the middle
      element also.
    */
    for (i=mid; i>=low; i--)
    {
      sum = sum+ar[i];
      if (sum>leftSum)
        leftSum = sum;
    }

    /*
      Similarly, finding the maximum
      sum of right subarray containing
      the adjacent right element to the
      middle element.
    */
    int rightSum = Integer.MIN_VALUE;
    sum = 0;

    for (i=mid+1; i<=high; i++)
    {
      sum=sum+ar[i];
      if (sum>rightSum)
        rightSum = sum;
    }

    /*
      returning the maximum sum of the subarray
      containing the middle element.
    */
    return (leftSum+rightSum);
  }

  // function to calculate the maximum subarray sum
  static int maxSumSubarray(int ar[], int low, int high)
  {
    if (high == low) // only one element in an array
    {
      return ar[high];
    }

    // middle element of the array
    int mid = (high+low)/2;

    // maximum sum in the left subarray
    int maximumSumLeftSubarray = maxSumSubarray(ar, low, mid);
    // maximum sum in the right subarray
    int maximumSumRightSubarray = maxSumSubarray(ar, mid+1, high);
    // maximum sum in the array containing the middle element
    int maximumSumCrossingSubarray = maxCrossingSubarray(ar, low, mid, high);

    // returning the maximum among the above three numbers
    return maximum(maximumSumLeftSubarray, maximumSumRightSubarray, maximumSumCrossingSubarray);
  }

  public static void main(String[] args) {
    int a[] = {3, -1, -1, 10, -3, -2, 4};
    System.out.println(maxSumSubarray(a, 0, 6));
  }
}

输出:-11
预期产量:-                    11
                   [3,-1,-1,10]

我如何跟踪开始和结束索引,尤其是使用递归?

1 个答案:

答案 0 :(得分:0)

maximum sum subarray的网络搜索导致带有以下Java代码的GeeksforGeeks文章Largest Sum Contiguous Subarray

static int maxSubArraySum1(int a[])
{
    int size = a.length;
    int max_so_far = Integer.MIN_VALUE, max_ending_here = 0;

    for (int i = 0; i < size; i++)
    {
        max_ending_here = max_ending_here + a[i];
        if (max_so_far < max_ending_here)
            max_so_far = max_ending_here;
        if (max_ending_here < 0)
            max_ending_here = 0;
    }
    return max_so_far;
}

现在我们要做的就是添加开始/结束索引的捕获:

static int maxSubArraySum(int... a) {
    int size = a.length;
    int max_so_far = Integer.MIN_VALUE, max_ending_here = 0;
    int max_ending_start = 0, max_start = 0, max_end = 0; // for capturing indexes

    for (int i = 0; i < size; i++) {
        max_ending_here = max_ending_here + a[i];
        if (max_so_far < max_ending_here) {
            max_so_far = max_ending_here;
            max_start = max_ending_start; // capture start index
            max_end = i + 1;              //     and end index of "max_so_far"
        }
        if (max_ending_here < 0) {
            max_ending_here = 0;
            max_ending_start = i + 1; // capture new start index of "max_ending_here"
        }
    }
    System.out.println("start=" + max_start + ", end=" + max_end + ": " +
                       Arrays.toString(Arrays.copyOfRange(a, max_start, max_end)));
    return max_so_far;
}

测试

System.out.println(maxSubArraySum(-2, -3, 4, -1, -2, 1, 5, -3));

输出

start=2, end=7: [4, -1, -2, 1, 5]
7