题目描述
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)

代码一

思想:
这题可以用两层循环求解,
第一层我们遍历整个数组,确定现在我们找的连续数组的边界在哪里
第二层我们遍历边界前(从后向前)的所有数,进行相加,一旦出现数字比我们当前拥有的max大的,我们就记录下来。这样我们可以确保最后的max是整个数组的连续子数组最大和。

  1. public class Solution {
  2. public static void main(String[] args) {
  3. int[] arr = new int[]{-2,-8,-1,-5,-9};
  4. System.out.println(FindGreatestSumOfSubArray(arr));
  5. }
  6. public static int FindGreatestSumOfSubArray(int[] array) {
  7. //找边界
  8. if(array.length==1)return array[0];
  9. if(array.length==0)return 0;
  10. int max = array[0];
  11. for(int i = 1;i<array.length;i++)
  12. {
  13. if(array[i]>max)max=array[i];
  14. int j = i-1;
  15. int temp = array[i];
  16. while(j>=0) {
  17. temp += array[j];
  18. if(temp>max)max=temp;
  19. j--;
  20. }
  21. }
  22. return max;
  23. }
  24. }

如果第二层从前向后遍历的话那么要求的连续子序列都是从0索引开始

  1. // public static int FindGreatestSumOfSubArray(int[] array) {
  2. // int sum = 0;
  3. // int j=0;
  4. // int temp = 0;
  5. // int index = 0;
  6. // for(int right = 0;right<array.length;right++)
  7. // {
  8. // while(j<=right) {
  9. // sum += array[j];
  10. // j++;
  11. // }
  12. // if(sum>=temp)
  13. // {
  14. // temp = sum;
  15. // index = right;
  16. // }
  17. // sum=0;
  18. // j=0;
  19. // }
  20. // return index;
  21. //
  22. // }

代码一

动态规划
1、新建一个长度和输入数组相同的int[] dp, 存储连续字数组的最大和。同时,我们需要定义这个list里的第一个数是array[0],因为第一个数只能有自己,前面没有别的数来和他形成连续子数组了。同时,我们创建一个int max,来实时记录当前的最大和。
2、遍历整个array,然后先新建一个int temp来储存当前遍历到的array[i]与前一位最大和的和,然后进行条件判断,如果这个temp大于当前的array[i](即当前遍历到的数),我们就将temp储存入dp[i],如果这个temp小于当前的array[i] (即如果我们只取当前这个数就已经比他加上原来所有的数都大了,我们便可以舍弃前面所有数,从这个数重新开始),我们将array[i]储存进dp[i]里
3、在2的遍历里,当我们走完上面的判断,我们还需要判断,当前的dp[i]是不是我们至今为止的最大和,如果是,更新我们前面创建的int max
结束循环后,我们返回int max即可,这便是我们整个连续子数组的最大和

  1. public static int FindGreatestSumOfSubArray(int[] array) {
  2. //动态规划
  3. int[] dp = new int[array.length];
  4. dp[0] = array[0];
  5. int temp = array[0];
  6. int max = dp[0];
  7. for(int i=1;i<array.length;i++)
  8. {
  9. temp = array[i]+dp[i-1];
  10. if(temp<array[i]) {
  11. dp[i]=array[i];
  12. }
  13. else
  14. {
  15. dp[i]=temp;
  16. }
  17. if(dp[i]>max) {
  18. max = dp[i];
  19. }
  20. }
  21. return max;
  22. }