最大字段和(分治法,递归,Java)

简介: 求子区间及最大和,从结构上是非常适合分治法的,因为所有子区间[start, end]只可能有以下三种可能性:在[0, (arr.length-1)/2]这个区域内在[(arr.length-1)/2+1, arr.length-1]这个区域内起点位于[0, (arr.length-1)/2],终点位于[(arr.length-1)/2+1, arr.length-1]内

分析

这里我们以数组 arr[]={-20,11,-4,13,-5,-2};  为例

求子区间及最大和,从结构上是非常适合分治法的,因为所有子区间[start, end]只可能有以下三种可能性:


在[0, (arr.length-1)/2]这个区域内

在[(arr.length-1)/2+1, arr.length-1]这个区域内

起点位于[0, (arr.length-1)/2],终点位于[(arr.length-1)/2+1, arr.length-1]内



以上三种情形的最大者,即为所求. 前两种情形符合子问题递归特性,所以递归可以求出. 对于第三种情形,则需要单独处理. 第三种情形必然包括了 (arr.length-1)/2 和 (arr.length-1)/2+1 两个位置,这样就可以利用第二种穷举的思路求出:


1. 以(arr.length-1)/2为终点,往左移动扩张,求出和最大的一个leftSum

2. 以(arr.length-1)/2+1为起点,往右移动扩张,求出和最大的一个rightSum

3. leftSum+rightSum=midSum      midSum是第三种情况可能的最大值

//最大子段
public class Maxsize {
    public static void main(String[] args) {
        int arr[]={-20,11,-4,13,-5,-2};
        System.out.println(maxsize(arr,0,arr.length-1));
    }
    public static int maxsize(int[] arr, int left, int right){
        int sum=0,midSum=0,leftSum=0,rightSum=0;
        int center,s1,s2,lefts,rights;
        //如果序列长度为1时
        if (left==right){
            sum=arr[left];
        }
        else {
            //划分
            center=(left+right)/2;
            //左递归
            leftSum=maxsize(arr,left,center);
            //又递归
            rightSum=maxsize(arr,center+1,right);
            s1=0;lefts=0;
            for (int i=center;i>=left;i--){
                lefts+=arr[i];
                if (lefts>s1){
                    s1=lefts;
                }
            }
            s2=0;rights=0;
            for (int j=center+1;j<=right;j++){
                rights+=arr[j];
                if (rights>s2){
                    s2=rights;
                }
            }
            midSum=s1+s2;
            if (midSum<leftSum){
                sum=leftSum;
            }
            else {
                sum=midSum;
            }
            if (sum<rightSum){
                sum=rightSum;
            }
        }
        return sum;
    }
}


相关文章
|
6天前
|
机器学习/深度学习 算法 Java
全排列(分治)(Java语言 +全排列模板)
全排列(分治)(Java语言 +全排列模板)
11 2
|
6天前
|
Java
java中递归实例
java中递归实例
19 0
|
6天前
|
Java
【Java】— —实现人物对象的增、删、改、查(注:对象的删除以逻辑删除为主,在person类中设置“删除状态字段”,字删除该字段时,将状态改为有效。)
【Java】— —实现人物对象的增、删、改、查(注:对象的删除以逻辑删除为主,在person类中设置“删除状态字段”,字删除该字段时,将状态改为有效。)
37 0
|
6天前
|
Java C语言
详解java方法与递归
详解java方法与递归
13 3
|
6天前
|
自然语言处理 Java 编译器
【Java探索之旅】方法重载 递归
【Java探索之旅】方法重载 递归
11 0
|
6天前
|
XML SQL 前端开发
【Java】实体字段传参类型线上问题记录
【Java】实体字段传参类型线上问题记录
24 1
|
6天前
|
SQL Java 关系型数据库
java 递归返回树形组织结构(附带树形菜单的搜索)
java 递归返回树形组织结构(附带树形菜单的搜索)
19 0
|
6天前
|
算法 JavaScript Java
Java多线程+分治求和,太牛了
`shigen`,一位擅长Java、Python、Vue和Shell的博主,分享编程知识和成长体验。在一次面试中因对高并发问题准备不足而受挫,随后深入学习,研究了线程池和经典案例——计算1亿数字的和。采用分治策略,`shigen`实现了Java版的归并排序,并对比了Python的简洁实现。通过多线程和分段求和优化,展示了如何高效解决大数求和问题,引入了分治思想的递归任务来进一步提升性能。未来将探讨`forkjoin`框架。关注`shigen`,每天学习新知识!
22 0
Java多线程+分治求和,太牛了
|
6天前
|
算法 Java
Java必刷入门递归题×5(内附详细递归解析图)
Java必刷入门递归题×5(内附详细递归解析图)
36 1
C4.
|
6天前
|
机器学习/深度学习 存储 搜索推荐
Java的递归
Java的递归
C4.
9 0