昨日课堂练习01——求数组中所有子数组最大的和

看一下题目:

  

 

 解法一:

  给出最简单解题思路,很容易理解,但时间复杂度不符合要求。

  

/*
*求一个整数数组的最大子数组之和
*思路:先定义一个整数数组,然后找出所有子数组求和,并比较他们的和,输出最大的结果
* 时间复杂度为o(n^3)
*/
复制代码
import java.util.Scanner;
/*
   *求一个整数数组的最大子数组之和
   *思路:先定义一个整数数组,然后找出所有子数组求和,并比较他们的和,输出最大的结果
   * 时间复杂度为o(n^3)
 */
public class SumArray {

    public static int max(int a,int b)
    {
        return a>b?a:b;
    }

    public static void main(String[] args) {

        //定义一个数组
        int []a = new int[5];
        int sum1 = 0,sum2=0;
        Scanner sc = new Scanner(System.in);
        int num = 0;
        for(int i = 0;i < a.length;i++){
            num = sc.nextInt();
            a[i] = num;
        }

        //找出该数组的所有子数组
        for(int i = 0;i < a.length;i++){//循环一:子数组的起始坐标为i,共有a.length个
          for(int k = a.length-1;k >= i;k--)//循环二:子数组的首项再数组中的下标为0的个数有a.length个
          {
              for(int j = k;j >= i;j--) //循环三:求子数组的和
              {
                  sum1 += a[j];
              }
              sum2 = max(sum1,sum2);    //取最大值
              sum1 = 0;
          }
        }
        System.out.println("最大子数组的和为:"+sum2);
    }
}
复制代码

解法二

  解题思路:

/*
*增强版求子数组的和
* 回顾上个版本求最大子数组的和的解题思路:先定义一个整数数组,然后找出所有子数组求和,并比较他们的和,输出最大的结果
* 我们发现算法的时间复杂度的增大是在找出所有数组并求和的步骤上,现在做出优化,我们直接找出和最大的子数组。
* 分析如下:
* 数组中最大子数组的求和计算过程是这样的,我们还是从子数组的首项就是数组的首项开始(单个数据元素的子数组)。
* 对下一项正负进行判断(若为正,则说明前一个子数组绝对不是和最大的子数组
* 若为负,则需进一步判断(先把上一个子数组的和保存下来sum1,因为上一数组可能就是和最大的子数组。
* 再进行判断(上个和加上后面为负数的一项,得出新的结果sum2。
* 再与后一项的数值比较,因为新的结果可能就小于后一项的值,比较后直接取较大的结果
* 结果较大的那一项为和较大的子数组)
* 找出和较大的子数组后,在于上一个保存的子数组的和比较,取最大值)
* 发现整个过程就是一个简单的递归,时间复杂度为o(n)。
* )
*/
复制代码
import java.util.Scanner;

public class SumArray2 {
    /*
    *增强版求子数组的和
    * 回顾上个版本求最大子数组的和的解题思路:先定义一个整数数组,然后找出所有子数组求和,并比较他们的和,输出最大的结果
    * 我们发现算法的时间复杂度的增大是在找出所有数组并求和的步骤上,现在做出优化,我们直接找出和最大的子数组。
    * 分析如下:
    *       数组中最大子数组的求和计算过程是这样的,我们还是从子数组的首项就是数组的首项开始(单个数据元素的子数组)。
    *       对下一项正负进行判断(若为正,则说明前一个子数组绝对不是和最大的子数组
    *                         若为负,则需进一步判断(先把上一个子数组的和保存下来sum1,因为上一数组可能就是和最大的子数组。
    *                                            再进行判断(上个和加上后面为负数的一项,得出新的结果sum2。
    *                                                      再与后一项的数值比较,因为新的结果可能就小于后一项的值,比较后直接取较大的结果
    *                                                      结果较大的那一项为和较大的子数组)
    *                                            找出和较大的子数组后,在于上一个保存的子数组的和比较,取最大值)
    *                          发现整个过程就是一个简单的递归,时间复杂度为o(n)。
    *                  ),
     */
    public static int max(int a,int b)
    {
        return a>b?a:b;
    }

    public static void main(String[] args) {

        //定义一个数组
        int []a = new int[100];
        int sum1 = 0,sum2=0;
        Scanner sc = new Scanner(System.in);
        int num = 0;
        for(int i = 0;i < 5;i++){
            num = sc.nextInt();
            a[i] = num;
        }
        sum1 = a[0];
        for(int i = 0;i<5;i++)
        {
            sum2 = sum1;
            if(a[i+1]<0){
                i++;
                sum1+=a[i];
                sum1 = max(sum1,a[i+1]);
            }else{
                sum1+=a[i+1];
            }
            sum1=max(sum2,sum1);
        }
        System.out.println("最大子数组的和为:"+sum1);
    }
}
复制代码

 

posted @   几人著眼到青衫  阅读(81)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示