402. 连续子数组求和

给定一个整数数组,请找出一个连续子数组,使得该子数组的和最大。输出答案时,请分别返回第一个数字和最后一个数字的下标。(如果两个相同的答案,请返回其中任意一个)

样例

给定 [-3, 1, 3, -3, 4], 返回[1,4].

想清楚这个问题这道题就差不多有解了:“什么时候更新start(第一个数字下标)和end(最后一个数字下标)?”

首先很直接的可以联想到用动态规划来做这个题,用一个vector来存每个位对应的到此位为止的最大子数组和

那么令F[n]表示为到n为止的最大子数组和,可以写出如下update公式

F[n]=max(F[n-1]+A[n], A[n])

如果是取前者,说明F[n-1]>=0, 此时end随n一起更新

如果是后者,说明F[n-1]<0,此时start和end重置为n

 1 vector<int> continuousSubarraySum(vector<int> &A) {
 2         // write your code here
 3         int start=0,end=0,sum=0,max=A[0];
 4         vector<int> res(2,0);
 5         vector<int> record;
 6         record.push_back(A[0]);
 7         for(int i=1;i<A.size();i++){
 8             if(record[i-1]<0){
 9                 record.push_back(A[i]);
10                 start=i;
11                 end=i;
12             }
13             else{
14                 record.push_back(A[i]+record[i-1]);
15                 end=i;
16             }
17             if(record[i]>max){
18                 max=record[i];
19                 res[0]=start;
20                 res[1]=end;
21             }
22         }
23         return res;
24     }

这样做的话,空间复杂度就上去了,这方面可以优化一下

我们用sum作为一个累加器,当sum为负的话,显然我们不应该继续累加了,因为不管怎样不可能得出更大的和,start应该重置到加到sum为负的后一个数

对于end,只要sum不为负,end就跟着加到sum上的数走

 1 vector<int> continuousSubarraySum(vector<int> &A) {
 2         // write your code here
 3         int start=0,end=0,sum=0,max=INT_MIN;
 4         vector<int> res(2,-1);
 5         for(int i=0;i<A.size();i++){
 6             if(sum<0){
 7                 sum = A[i];
 8                 start = i;
 9                 end=i;
10             }
11             else{
12                 sum+=A[i];
13                 end=i;
14             }
15             if(sum>max){
16                 max=sum;
17                 res[0]=start;
18                 res[1]=end;
19             }
20         }
21         return res;
22     }

原文地址:https://www.cnblogs.com/TheLaughingMan/p/8309462.html

时间: 2024-08-03 06:52:54

402. 连续子数组求和的相关文章

lintcode循环数组之连续子数组求和

v 题目:连续子数组求和 II 给定一个整数循环数组(头尾相接),请找出一个连续的子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的值.如果多个答案,请返回其中任意一个. v 样例 给定 [3, 1, -100, -3, 4], 返回 [4,0]. v 思路 1.如果不是循环数组,求解连续子区间和的思路如下: 首先设一个累加变量和sum和最大值变量maxN,[ld, rd]表示当前正在累加的区间,[lt,rt]表示最大和的区间.从左边开始一直累加,并初始当前区间[ld

求环形连续子数组的和的最大值

课上老师把连续子数组求和的题目改为让子数组首尾相接再求最大子数组的和. 我的处理方法:新建一个二倍原数组长度b的数组d[  ],然后从d[0]到d[b]分别生成b个分数组,再分别求子数组和,再比较. package wodeshiyao; import java.util.Scanner; public class shiyan321 { static Scanner scan=new Scanner(System.in); public static void main(String[] ar

最大连续子数组和与JUnit测试

[题目]最大连续子数组和(最大子段和) 背景 问题: 给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],-,a[n],求该序列如a[i]+a[i+1]+-+a[j]的子段和的最大值.当所给的整数均为负数时定义子段和为0,依此定义,所求的最优值为:Max{0,a[i]+a[i+1]+-+a[j]},1<=i<=j<=n 例如,当(a[1],a[2],a[3],a[4],a[5],a[6])=(-2,11,-4,13,-5,-2)时,最大子段和为20. -- 引用自<百

[算法导论]4.1-5最大连续子数组问题

在线性时间内非递归的求数组的最大连续子数组(连续和最大的子数组). 题目给出思路为数组A[1...j+1]的最大和子数组,有两种情况:a) A[1...j]的最大和子数组; b) 某个A[i...j+1]的最大和子数组,但思考很久没有理解如何用这个思路设计线性时间算法,希望有人能给予指点. (i点是使A[1]+..+A[i]为负的一个值?) 目前的思路是,最大子数组一定位于从某个正数开始,全部求和<=0的一段数组中 从其实点i到目标点j,从第一个正数开始截取尽量长的一段数组,从第一个正数起的最大

Task 4 求数组的连续子数组的最大和(团队合作)

小组成员:李敏.刘子晗 1.设计思想:由于已经做过这个题目,只要对之前的程序加上相应的测试和约束即可.我们两个人一起商议后,决定了程序的主框架和并列出了最终可以实现的功能.先要定义数组长度和上下限的变量,然后通过if语句对用户所给出的长度和数值进行判断看是否合法,如果不合法要重新输入.最后再加上之前求和的相应代码即可. 2.出现的问题:我们达成协议后,李敏负责编程,我负责测试.开始写程序,在写判断数值是否满足int整型范围的时候出现了错误,我在测试的时候发现她把小于号错写成了大于号,然后加以改正

最大子数组问题(求连续子数组的最大和)

在<算法导论>第四章分治策略(Divider and Conquer)4.1节提出了最大子数组问题.其转化就是求数组a={1, -2, 3, 10, -4, 7 , 2, -5}中连续子数组的最大和. 对于这个问题,很容想到一种暴力求解的方法:简单地尝试对所有可能的的组合进行求和.对数组为n存在n*(n-1)/2中组合,然后对每个组合进行求和.即三个for循环遍历,求出数组中每一个子数组的和,最终求出这些子数组的最大的一个值.记Sum[i,...,j]为数组a中第i个元素到第j个元素的和(其中

连续子数组的最大和Java实现

问题描述: 一个数组有 N 个元素,求连续子数组的最大和. 例如:[-1,2,1],和最大的连续子数组为[2,1],其和为 3 本文采用的是数组,利用等差数列进行求和,代码如下: package series00; import java.util.Arrays;import java.util.Scanner; public class series1 { public static void main(String[] args) { //准备数据 System.out.println("请

求连续子数组的最大和

一.题目: 这是一道考的烂的不能再烂的题目,但是依然有很多公司乐于将这样的题目作为笔试或面试题,足见其经典. 问题是这样的:一个整数数组中的元素有正有负,在该数组中找出一个连续子数组,要求该连续子数组中各元素的和最大,这个连续子数组便被称作最大连续子数组.比如数组{2,4,-7,5,2,-1,2,-4,3}的最大连续子数组为{5,2,-1,2},最大连续子数组的和为5+2-1+2=8. 二.解法: 解法一:暴力求解法 /* (1) 常规方法,时间复杂度O(n*n) (2) 先从第一个元素开始向后

一个数组中连续子数组的最大和

//连续子数组的最大和     //{ 1, -2, 3, 10, -4, 7, 2, -5 };//最大子数组18     #include<iostream>     using namespace std;     bool g_InValid = false;     int FindGreatSumOfSubArray(int* arr, int size)     {     if (arr == NULL || size <= 0)     g_InValid = true