package beautyOfCoding;
public class MaxSubArraySum {
/**
* 3.求子数组的最大和
题目描述:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,
因此输出为该子数组的和18。
下面的解法:数组元素全是负数时,认为子数组最大和为0
*/
public static void main(String[] args) {
int[] a={-1,-2,-3,-10};
// int[] a={1, -2, 3, 10, -4, 7, 2, -5};
maxSubArraySum3(a);
maxSubArraySum2(a);
maxSubArraySum(a);
}
/*2012-07-29 编程之美书上的这个分析比较好理解,因此我写了maxSubArraySum2。其实maxSubArraySum2可以轻易地转换成maxSubArraySum。这两个方法本质是一样的。
假设A[0],A[1],...A(n-1)的最大子段为A[i],...,A[j],则有以下3种情况
1)当0=i=j的时候,元素A[0]本身构成和最大的一段
2)当0=i<j的时候,和最大的一段以A[0]开头
3)当0<i时候,元素A[0]跟和最大的一段没有关系
Start[i]表示从第i个元素开始(包括第i个元素)的子数组和最大值,All[i]表示A[i]A[i+1]...A[n-1]这个数组的子数组和的最大值
则原始问题A[0],A[1],...A(n-1)的解All[0]=max{A[0],A[0]+Start[1],ALL[1]}
*/
static void maxSubArraySum2(int[] a){
//略去参数检查
int Start=0;
int All=0;
for(int i=0,len=a.length;i<len;i++){
All=max(a[i],Start+a[i],All);
Start=max(a[i],a[i]+Start); //if start<0, start=a[i]
}
System.out.println("maxSubArraySum="+All);
}
static int max(int x,int...y){
int max=x;
for(int i:y){
if(i>max){
max=i;
}
}
return max;
}
static void maxSubArraySum(int[] a){
int len=a.length;
int sum=0;
int max=0;
int lastIndex=-1;
for(int i=0;i<len;i++){
if(sum<=0){
sum=a[i];
}else{
sum+=a[i];
}
if(sum>max){
max=sum;
lastIndex=i;
}
}
System.out.println("maxSubArraySum="+max);
if(lastIndex!=-1){
System.out.println("and the subArray is:");
//print the sub array
int i=lastIndex;
while(i>=0&&sum>=0){
sum-=a[i];
i--;
}
for(int j=i;j<=lastIndex;j++){
System.out.print(a[j]+" ");
}
}
}
/*下面这个方法是编程之美里面在讲二维数组的子数组最大和时候提到的:
p[0]=a[0],
p[i]=p[i-1]+a[i]=a[0]+a[1]+...a[i],1<=i<=(n-1)
那么
a[i]+a[i+1]+...a[j]=p[j]-p[i-1]
子数组和最大值为max(p[j]-p[i]),0<=(i,j)<=(n-1)
*/
static void maxSubArraySum3(int[] a){
//略去参数检查
boolean allNegative=true;
int len=a.length;
int[] p=new int[len];
for(int i=0;i<len;i++){
if(allNegative){
if(a[i]>0){
allNegative=false;
}
}
if(i==0){
p[0]=a[0];
}else{
p[i]=p[i-1]+a[i];
}
}
if(allNegative){
System.out.println("maxSubArraySum=0");
}else{
int max=p[0];
int min=p[0];
for(int i=0;i<len;i++){
if(p[i]>max){
max=p[i];
}
if(p[i]<min){
min=p[i];
}
}
System.out.println("maxSubArraySum="+(max-min));
}
}
}
分享到:
相关推荐
"Java实现求子数组和的最大值算法示例" 本文主要介绍了Java实现求子数组和的最大值算法,涉及Java数组遍历、判断、运算等相关操作技巧。下面是对该算法的详细讲解和分析。 首先,需要了解子数组的概念。子数组是...
求子数组的最大和** - **题目背景**:数组是计算机科学中最常用的数据结构之一。本题考查的是如何找到数组中连续子数组的最大和。 - **解题思路**:本题可以使用动态规划的方法解决。设`dp[i]`表示以第i个元素...
### 1....以上四个问题的解决方案涵盖了从二元查找树到排序的双向链表转换、特殊栈的设计、求子数组的最大和以及在二元树中寻找特定和的路径等多个方面,涉及到了数据结构和算法的核心思想和技术细节。
讨论了求子数组的最小长度st的问题,子数组中所有元素的总和不小于给定的s。 ---雷 2020-2-22 讨论组合问题 Lei 提交了一些 Leetcode 问题的解决方案,但不是 Yoon-G 指定的那些问题 Yoon-G 介绍了特里概念和分词...
Java小程序涵盖了多个编程知识点,这些都是Java开发者经常遇到的基础和进阶问题。让我们逐一解析这些主题: 1. **质数**:质数是大于1且只有两个正因数(1和自身)的自然数。在Java中,我们可以使用循环或递归来...
##### 1.2.4 求子数组的最大和 - **问题描述**:给定一个整数数组,求其所有子数组中的最大和。 - **解决方案**: - 使用动态规划的思想解决。 - 定义 dp[i] 表示以 i 结尾的子数组的最大和。 - 状态转移方程为 ...
两数之和:本题考察了Java中数组的操作和排列组合的概念,了解Java中数组的基本概念和操作。 3. 递归:NC68.跳台阶:本题考察了Java中的递归概念和应用场景,了解递归的基本概念和应用。 4. 快速排序 HJ3.明明的...
#### 三、求子数组的最大和 **知识点概述:** 这是一个经典的动态规划问题,要求在 O(n) 时间内找到给定数组中的子数组的最大和。 **解决方案:** 采用动态规划的思想,用 `maxSum` 表示截止到当前位置的最大子...