最大子数组(循环连接)

Posted 立木-Six

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大子数组(循环连接)相关的知识,希望对你有一定的参考价值。

设计思想:

  把一个数组连成环,查找这个环的和最大的连续子数组时走到原来的数组尾部可以再继续加第一个元素,所以等价于构建一个原来数组2倍的数组

  查找和最大的连续子数组方法:
设原先数组两倍的数组名为a,长度为2n - 1,原数组长度为n

   

package zuoYe;

import java.util.Scanner;


public class MaxSubArray {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        
        
        //输入数据
        System.out.println("请输入数组长度");
        int n = scan.nextInt();
        int[] a = new int[n];
        
        System.out.println("请输入数组元素");
        for(int i = 0;i < n;i++)
        {
            a[i] = scan.nextInt();
        }
        scan.close();
        //计算此数组的和最大的连续子数组
        int[] result = maxSub(a,a.length);
        System.out.println("不连接成环的和最大的连续子数组:");
        for(int i = result[0];i <= result[1];i++)
        {
            System.out.print(a[i] + "\t");
        }
        System.out.println("和为:" + result[2]);
    
    
        
        
        //将此数组连成一个环,再计算此数组的和最大的连续子数组
        //连成一个环即将数组后再接上此数组,但是数组的最后一个元素不用接,相当于计算接上之后的数组的和最大子数组
        int[] b = new int[2 * n - 1];
        for(int i = 0;i < n - 1;i++)
        {
            b[i] = a[i];
            b[n + i] = a[i];
        }
        b[n - 1] = a[n - 1];
        int[] result2 = maxSub(b,n);
        System.out.println("\n\n将数组连成环后的和最大的连续子数组:");
        for(int i = result2[0];i <= result2[1];i++)
        {
            System.out.print(b[i] + "\t");
        }
        System.out.println("和为:" + result2[2]);

        
    }
    
    
    
    
    //计算a数组的和最大的连续子数组(a数组为连成环后的等价数组,即原数组的二倍,n为原数组的长度)
    public static int[] maxSub(int[] a,int n)
    {
        int an = a.length;//连成环的等价数组的长度
        int currectSum = a[0];//记录当前累加和,初始值为a[0]
        int currectStartIndex = 0;//记录当前累加的起始下标,初始值为0
        int count = 1;//记录累加元素的个数,初始值为1
        int[] result = new int[3];//记录结果子数组的信息,
        result[0] = 0;//结果子数组的开始下标
        result[1] = 0;//结果子数组的结束下标
        result[2] = a[0];//结果子数组的和
        for(int i = 1;i < an;i++)//依次遍历a数组的每个元素
        {
            if(currectSum <= 0)//如果当前累加和不大于0,不大于0对后续的元素没有贡献,可以去掉了,所以应从a[i]处重新开始加
            {
                currectSum = a[i];//将当前累加和赋值为a[i]
                currectStartIndex = i;//将当前累加的开始下标赋值为i
                count = 1;//将累加元素的个数记为1
            }
            else//当前累加和大于0,则继续加a[i]
            {
                currectSum += a[i];
                count++;//当前累加元素的个数加一
            }
            if(currectSum > result[2])//如果当前累加和大于原结果数组的累加和result[2],则应该将结果子数组信息更新为当前子数组,因为当前子数组的累加和大于结果子数组的和
            {
                result[0] = currectStartIndex;//结果子数组的开始下标为当前子数组的开始下标
                result[1] = i;//结果子数组的结束下标赋值为i
                result[2] = currectSum;//结果子数组的累加和赋值为当前子数组的累加和
            }
            if(count >= n)//如果累加的元素个数等于原数组(未连成环的数组)的长度,则说明已经加了最多的元素,不能再加了,也就是说和最大的子数组即为原数组,应该结束循环
            {
                break;
            }
        }
        return result;
    }
    
    
    
}

 

以上是关于最大子数组(循环连接)的主要内容,如果未能解决你的问题,请参考以下文章

求最大子数组(循环数组)

整数组中取最大子数组

51Nod 1050 循环数组最大子段和 dp

循环数组的子数组最大和

求一维循环数组最大子数组

课堂练习