最大子列和问题(Java语言实现)

简介: 最大子列和问题(Java语言实现)

最大子列和问题(Java语言实现)


一、问题描述:给定N个整数的序列{ A 1 , A 2 , . . . , A n } ,求函数image.png的最大值,即求A i 到A j 连续的一段子列和最大的值。例如:某序列为{-1,-2,5,6,-11,8},则其最大子列和为11.


二、问题分析::一个整数序列中,可以产生出无数个子列,每个子列的和一般不相同,在此我们要求最大的子列,显然负数范围的子列和我们就不会考虑在内,因此如果所得结果小于0的数,则返回0做为结束


三、Java语言实现:


1.算法1: 暴力求解法,使用三重循环来求解,数据量小的时候没有问题,但是一旦数据量大,运行时间会很长,因为其时间复杂度为:T(n)=O(n 3 ) ,这是非常之恐怖的!以下是实现代码,数据量大的时候不推荐使用


import java.util.Scanner;
//三重循环方式
public class MaxSubseqSum1 {
    public  static void main(String[] args){
        System.out.println("请输入整数列的大小:");
        Scanner input=new Scanner(System.in);
        int N=input.nextInt();
        int [] A=new int[N];
        System.out.println("请输入整数列元素:");
        for (int i = 0; i < N; i++) {
            A[i]=input.nextInt();
        }
        System.out.println("整数列为:");
        for (int i = 0; i < N; i++) {
            System.out.print(" "+A[i]);
        }
        System.out.println();
        System.out.println("最大子列和为:"+MaxSubseqSum1.FindMaxSubseqSum1(A,N));
    }
    public  static int FindMaxSubseqSum1(int [] A,int N ) {
        int MaxSum=A[0];
        for (int i = 0; i < N; i++) {
            for (int j = i; j < N; j++) {
                int ThisSum = 0;
                for (int k = i; k < j; k++) {
                    ThisSum += A[k];
                }
                if (ThisSum > MaxSum) {
                    MaxSum = ThisSum;
                }
            }
        }
        return MaxSum;
    }
}

2.算法2: 改进的暴力求解法。思想:对于求和的问题,例如要求某数列的前n项和,我们可以采用前k项和 = 前k-1项和+第k项的方法来求解。于是可以将算法1的第三层循环进行改进,代码如下:

import java.util.Scanner;
public class MaxSubseqSum2 {
    public  static void main(String[] args){
        System.out.println("请输入整数列的大小:");
        Scanner input=new Scanner(System.in);
        int N=input.nextInt();
        int [] A=new int[N];
        System.out.println("请输入整数列元素:");
        for (int i = 0; i < N; i++) {
            A[i]=input.nextInt();
        }
        System.out.println("整数列为:");
        for (int i = 0; i < N; i++) {
            System.out.print(" "+A[i]);
        }
        System.out.println();
        System.out.println("最大子列和为:"+MaxSubseqSum2.FindMaxSubseqSum2(A));
    }
    public static int FindMaxSubseqSum2(int [] A){
        int MaxSum=A[0];
        int ThisSum;
        for (int i = 0; i < A.length; i++) {
            ThisSum=0;
            for (int j = i; j < A.length; j++) {
                ThisSum+=A[j];    //改进
                if (ThisSum>MaxSum){
                    MaxSum=ThisSum;
                }
            }
        }
        return MaxSum;
    }
}

但是,这个算法还是使用了二重循环,数据量小的时候没有问题,但是一旦数据量大,运行时间会很长,因为其时间复杂度为:T(n)=O(n 2) 。算法2已经成功地将算法1的时间复杂度降了1阶,那我们还能不能继续将算法2的复杂度降低呢?显示是可以的!一名优秀的程序员,在得到时间复杂度为T(n)=O(n 2 )的算法之后,总是希望将时间复杂度降到T(n)=O(n l o g n )!


3.算法3: 分而治之


步骤:

1.将序列从中分为左右两个子列

2.递归求得两个子列的最大和

3.从子列的中分点分头向左右两边扫描,找出跨越分界线的最大子列和

4.输出这三个最大子列和中最大的一个

我也是第一次接触分治算法,理解还不是很透彻,后期再慢慢补吧,贴上代码:

import java.util.Scanner;
public class MaxSubseqSum3 {
    public static void main(String[] args){
        System.out.println("请输入整数列的大小:");
        Scanner input=new Scanner(System.in);
        int N=input.nextInt();
        int [] A=new int[N];
        System.out.println("请输入整数列元素:");
        for (int i = 0; i < N; i++) {
            A[i]=input.nextInt();
        }
        System.out.println("整数列为:");
        for (int i = 0; i < N; i++) {
            System.out.print(" "+A[i]);
        }
        System.out.println();
        System.out.println("最大子列和为:"+MaxSubseqSum3.DivideAndConquer(A,0,A.length-1));
                                      //left为数组起点,right为数组中点.
    }
    public static int DivideAndConquer(int [] A,int left,int right){
        int MaxLeftSum,MaxRightSum;//存放左、右子列的最大子列和
        int MaxLeftBorderSum,MaxRightBorderSum;//存放跨分界线的左、右子列的最大子列和
        int leftBorderSum,rightBorderSum;//存放放跨分界线的左、右子列的子列和
        int center;//存放分点的下标
        //终止条件,子列只有一个数字
        if(left==right){
            if (A[left]>0){
                return A[left];
            }
            else
                return 0;
        }
        //分的过程
        center=(left+right)/2;
        MaxLeftSum=DivideAndConquer(A,left,center);//递归求左子列和
        MaxRightSum=DivideAndConquer(A,center+1,right);//递归求右子列和
        //求跨分界的最大子列和
        MaxLeftBorderSum=0;
        leftBorderSum=0;
        for (int j = center; j > left; j--) {
            leftBorderSum+=A[j];
            if (leftBorderSum>MaxLeftBorderSum){
                MaxLeftBorderSum=leftBorderSum;
            }
        }//左边扫描结果
        MaxRightBorderSum=0;
        rightBorderSum=0;
        for (int j = (center+1);  j < right; j++) {
            rightBorderSum+=A[j];
            if(rightBorderSum>MaxRightBorderSum){
                MaxRightBorderSum=rightBorderSum;
            }
        }//右边扫描结果
        return MaxSubseqSum3.FindMax(MaxLeftSum,MaxRightSum,MaxLeftBorderSum+MaxRightBorderSum);
    }
    public static int FindMax(int a,int b,int c){
        return (a>b)?((a>c)?a:c):((b>c)?b:c);
    }
}


分而治之算法的时间复杂度是T(n)=O(n l o g n nlognnlogn),已经是一个比较好的算法了,还有一个时间复杂度更低的算法

4.算法4:在线处理算法 思想:每扫描到一个元素,就求出和ThisSum,然后进行判断,如果ThisSum大于MaxSum,就更新MaxSum=ThisSum;如果ThisSum小于0,就直接令ThisSum=0;重复上述步骤,直到扫描完数组的所有元素,返回MaxSum。以下是代码实现:

import java.util.Scanner;
public class MaxSubseqSum4 {
    public static void main(String [] args){
        System.out.println("请输入整数列的大小:");
        Scanner input=new Scanner(System.in);
        int N=input.nextInt();
        int [] A=new int[N];
        System.out.println("请输入整数列元素:");
        for (int i = 0; i < N; i++) {
            A[i]=input.nextInt();
        }
        System.out.println("整数列为:");
        for (int i = 0; i < N; i++) {
            System.out.print(" "+A[i]);
        }
        System.out.println();
        System.out.println("最大子列和为:"+MaxSubseqSum4.OnlineProcess(A));
    }
    public static int OnlineProcess(int [] A){
        int ThisSum=0,MaxSum=A[0];
        for (int i = 0; i < A.length; i++) {
            ThisSum+=A[i];
            if (ThisSum>MaxSum){
                MaxSum=ThisSum;
            }
            else if (ThisSum<0){
                ThisSum = 0;
            }
        }
        return MaxSum;
    }
}

时间复杂度仅为T(n)=O(n),所以这个算法以及非常快了,但有优点就有缺点,缺点就是它容易出错。


五、总结


还有最后6天就要到大三了,从昨天才开始系统的学习数据结构和算法,希望自己能够坚持下去,在学习Java开发的内容时也不要放弃了数据结构和算法的学习。我是先跟着慕课浙大数据结构来学习的,计划每天学习一节内容,并实现上面的算法。加油!

相关文章
|
4月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
125 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
5天前
|
存储 缓存 Java
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
20 3
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
|
3月前
|
监控 Java API
如何使用Java语言快速开发一套智慧工地系统
使用Java开发智慧工地系统,采用Spring Cloud微服务架构和前后端分离设计,结合MySQL、MongoDB数据库及RESTful API,集成人脸识别、视频监控、设备与环境监测等功能模块,运用Spark/Flink处理大数据,ECharts/AntV G2实现数据可视化,确保系统安全与性能,采用敏捷开发模式,提供详尽文档与用户培训,支持云部署与容器化管理,快速构建高效、灵活的智慧工地解决方案。
|
30天前
|
Oracle Java 关系型数据库
Java基础(一):语言概述
Java基础(一):语言概述
Java基础(一):语言概述
|
5天前
|
缓存 Java 应用服务中间件
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
27 5
|
1月前
|
存储 监控 算法
探秘局域网桌面监控:深入剖析 Java 语言核心算法
在数字化办公时代,局域网桌面监控如同企业的“智慧鹰眼”,确保工作效率与数据安全。本文以Java为载体,揭示哈希表在监控中的关键应用。通过高效的数据结构和算法,哈希表能快速索引设备连接信息,大幅提升监控的时效性和响应速度。代码示例展示了如何用Java实现设备网络连接监控,结合未来技术如AI、大数据,展望更智能的监控体系,助力企业在数字化浪潮中稳健前行。
|
3月前
|
SQL 安全 Java
安全问题已经成为软件开发中不可忽视的重要议题。对于使用Java语言开发的应用程序来说,安全性更是至关重要
在当今网络环境下,Java应用的安全性至关重要。本文深入探讨了Java安全编程的最佳实践,包括代码审查、输入验证、输出编码、访问控制和加密技术等,帮助开发者构建安全可靠的应用。通过掌握相关技术和工具,开发者可以有效防范安全威胁,确保应用的安全性。
71 4
|
4月前
|
Java 程序员 编译器
在Java编程中,保留字(如class、int、for等)是具有特定语法意义的预定义词汇,被语言本身占用,不能用作变量名、方法名或类名。
在Java编程中,保留字(如class、int、for等)是具有特定语法意义的预定义词汇,被语言本身占用,不能用作变量名、方法名或类名。本文通过示例详细解析了保留字的定义、作用及与自定义标识符的区别,帮助开发者避免因误用保留字而导致的编译错误,确保代码的正确性和可读性。
87 3
|
4月前
|
移动开发 Java 大数据
深入探索Java语言的核心优势与现代应用实践
【10月更文挑战第10天】深入探索Java语言的核心优势与现代应用实践
163 4
|
4月前
|
分布式计算 安全 Java
Java语言的特点?
Java语言的特点?

热门文章

最新文章