当前位置:   article > 正文

最大子序列和问题的求解_完成最大序列和问题的求解。

完成最大序列和问题的求解。

       问题描述:给定(可能存在负值)整数A1,A2.....An,求最大子序列和。如果所有的整数均为负数,则最大子序列和为0.

列如:对于输入-2,11,-4,13,-5,-2,该输入的最大子序列和为20(11-4+13).


        现在我们将叙述四个算法来求解最大子序列和问题。

      1. 该算法是使用穷举法来尝试所有的可能 算法如下

  1. public static int maxSubSum1(int [] a)
  2. {
  3. int maxSum=0;
  4. for(int i=0;i<a.length;i++)
  5. {
  6. for(int j=i;j<a.length;j++)
  7. {
  8. int thisSum=0;
  9. for(int k=i;k<j;k++)
  10. {
  11. thisSum +=a[k];
  12. }
  13. if(thisSum>maxSum)
  14. {
  15. maxSum=thisSum;
  16. }
  17. }
  18. }
  19. return maxSum;
  20. }
该算法的时间复杂度为O(N3)

       第一个算法的第三个for循环中有大量不必要的重复计算,如:计算i到j的和,然而i到j-1的和在前一次的循环中已经计算过,无需重复计算,故该for循环可以去掉


算法2 

  1. public static int maxSubSum2(int [] a)
  2. {
  3. int maxSum=0;
  4. for(int i=0;i<a.length;i++)
  5. {
  6. int thisSum=0;
  7. for(int j=i;j<a.length;j++)
  8. {
  9. thisSum +=a[j];
  10. if(thisSum>maxSum)
  11. {
  12. maxSum=thisSum;
  13. }
  14. }
  15. }
  16. return maxSum;
  17. }
该算法的复杂度为O(N2).


       对于这个问题有一个递归解法,该方法采用一种分治的策略。其想法是把问题分为两个大致相等的子问题。然后递归地对他们求解,在使用分治的时候,最大子序列可能出现在三个不同的部位,可能出现在左半部分,可能出现在右半部分,也可能出现在出现在左右交界处,前两种情况可以递归求解,第三种情况的最大和可以通过求出前半部分的最大和以及后半部分的最大和,然后将两个结果进行相加,考虑下列输入:


        其中前半部分的最大和为6(从元素A1到A3)而后半部分的最大子序列和为8(从元素A6到A7)

        前半部分包含其最后一个元素的最大和为4,而后半部分包含其第一个元素的最大和为7,因此跨越这两个部分且通过中间的最大和为11.

  1. private static int maxSumRec(int [] a int left,int right)
  2. {
  3. if(left ==right )
  4. {
  5. if(a[left]>0)
  6. {
  7. return a[left];
  8. }
  9. else
  10. {
  11. return 0;
  12. }
  13. }
  14. int center=(left+right)/2;
  15. int maxLeftSum=maxSumRec(a,left,center);
  16. int maxRightSum=maxSumRec(a,center+1;right);
  17. int maxLeftBorderSum=0;leftBorderSum=0;
  18. for(int i=center;i>=left;i--)
  19. {
  20. leftBorderSum+=a[i];
  21. if(leftBorderSum>maxLeftBorderSum)maxLeftBorderSum=leftBorderSum;
  22. }
  23. int maxRightBorderSum=0;rightBorderSum=0;
  24. for(int i=center+1;i<=right;i++)
  25. {
  26. rightBorderSum +=a[i];
  27. if(rightBorderSum>maxRightBorderSum)maxRightBorderSum=rightBorderSum;
  28. }
  29. return max(maxLeftSum,maxRightSum,maxLeftBorderSum+maxRightBorderSum);
  30. }
  31. private static int max(int left,int right,int middle)
  32. {
  33. int max=0;
  34. if(max<=left)max=left;
  35. if(max<=right)max=right;
  36. if(max<=middle)max=middle;
  37. return max;
  38. }


算法四

  1. private static int maxSubSum4(int [] a)
  2. {
  3. int maxSum=0;thisSum=0;
  4. for(int j=0;j<a.lemgth;j++)
  5. {
  6. thisSum +=a[j];
  7. if(thisSum>maxSum)maxSum=thisSum;
  8. else if(thisSum<0)thisSum=0;
  9. }
  10. return maxSum;
  11. }

算法四的时间复杂度为O(N)










声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/497314
推荐阅读
相关标签
  

闽ICP备14008679号