子数组和最接近零问题

子数组和最接近零问题:

对于长度为N的数组A,求连续子数组的和最接近0的值。

如:1,-2,3,10,-4,7,2,-5;该数组中子数组和最接近零的值为0,子数组为-4,7,2,-5。

程序实现:

 1 /***************************************
 2 FileName NearZeroSubArray.cpp
 3 Author : godfrey
 4 CreatedTime : 2016/5/3
 5 ****************************************/
 6 #include <iostream>
 7 #include <cstring>
 8 #include <vector>
 9 #include <algorithm>
10 #include <stdio.h>
11 #include <stdlib.h>
12
13 using namespace std;
14
15 int NearZeroSubArray(int* A,int size){
16     int sum[size+1];
17     memset(sum,0,(size+1)*sizeof(int));
18     for(int i=1;i<size;i++){
19         sum[i+1] = sum[i] + A[i];
20     }
21     sort(sum,sum+size+1);
22     int difference = abs(sum[1] - sum[0]);
23     int result = difference;
24     for(int i=1;i<size;i++){
25         difference = sum[i+1] - sum[i];
26         result = min(difference,result);
27     }
28     return result;
29 }
30 int main()
31 {
32     int a[] = {1,-2,3,10,-4,7,2,-5};
33     int result = NearZeroSubArray(a,sizeof(a)/sizeof(int));
34     cout<<"the FindNearZeroNum: ";
35     cout<<result<<endl;
36     return 0;
37 }

运行结果:

说明:本算法时间复杂度为O(nlogn)。

转载请注明出处:

C++博客园:godfrey_88

http://www.cnblogs.com/gaobaoru-articles/

时间: 2024-08-23 11:46:21

子数组和最接近零问题的相关文章

最大连续子数组和与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. -- 引用自<百

LintCode_138——子数组和为零

题目: 给定一个整数数组,找到和为零的子数组.你的代码应该返回满足要求的子数组的起始位置和结束位置. 样例 给出[-3, 1, 2, -3, 4],返回[0, 2] 或者 [1, 3]. 解题思路: 依次求数组的前缀和,同时执行如下操作: 假定当前位置是i,查找i之前位置的前缀和,是否存在j位置,使得,j位置的前缀和 等于 i位置的前缀和. 若有,则j 到 i 之间的区间数的和为0. 直到遍历完整个数组. 时间复杂度O(n),空间复杂度O(n). 实现代码: class Solution { p

LintCode-最接近零的子数组和

给定一个整数数组,找到一个和最接近于零的子数组.返回第一个和最有一个指数.你的代码应该返回满足要求的子数组的起始位置和结束位置 样例 给出[-3, 1, 1, -3, 5],返回[0, 2],[1, 3], [1, 1], [2, 2] 或者[0, 4] 挑战 O(nlogn)的时间复杂度 分析:首先O(n^2)的算法很好想,直接枚举起点就行,看到挑战的复杂度,想肯定要排序或者二分什么的,这里没找出能二分的性质来,所以想只能想排序了,我们知道连续数组的和其实就是前缀和之间的差,而要求和最接近于零

子数组之和

给定一个整数数组,找到和为零的子数组.你的代码应该返回满足要求的子数组的起始位置和结束位置 样例 给出[-3, 1, 2, -3, 4],返回[0, 2] 或者 [1, 3]. 思路:这道题最开始我的想法是用两重宣传去查找第一组连续数字和为0的两端,会发现这种情况算法的复杂度是O(n*n);应该是挺复杂的方法:之后又看到了这样的算法,我们从第一个开始,把对于每一个元素而言的前n项和求出来,当出现sum(j)=sum(i)(j>i)时,即可认为第i+1项到第j项的总和为0:这是一个很巧妙的算法.所

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

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

【编程之美】求数组的子数组之和的最大值

一个有N个整数元素的一维数组A[0],A[1],......,A[n-1],这个数组当然有很多子数组,那么子数组的最大值是什么呢? 分析与解法 我们先明确题意: 1. 题目说的子数组,是连续的: 2. 题目只需要求和,并不需要返回子数组的具体位置: 3. 数组中的元素是整数,所以数组可能包含有正整数.零.负整数: 4. 子数组不为空. 解法一:枚举 最简单的办法就是枚举所有的i和j,计算sum[i..j] = A[i]+A[i+1]+...+A[j],遍历所有可能的sum[i..j],找到最大值

一维数组子数组最大和

题目:返回一个一维整数数组中最大子数组的和. 要求: 输入一个一维整形数组,数组里有正数也有负数. 一维数组首尾相接,象个一条首尾相接带子一样. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值. 设计思想: 生成数组,生成子数组,求和,求最大值. 代码: package bao; import java.util.*; public class Msum { public static void main(String args[]) { Scanne

子数组的最大和[算法]

题目:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的 和的最大值.要求时间复杂度为O(n). 例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,因此输出为该子数组的和18. 这个题我的第一感觉就是3层for循环直接进行么,就喜欢暴力for循环,遍历所有可能,还是自己的想法太low 了,其实这个题的时间复杂的度可以变为o(n),下面的代码分别用3个不一样的时间

2.13 子数组的最大乘积

题目: 给定一个长度为N的整形数组,只允许用乘法,不能用除法.计算任意N-1个数的组合中乘积最大的一组. 方法一: #include <iostream> #define MAXN 10000 using namespace std; int n, a[MAXN], s[MAXN], t[MAXN], p[MAXN]; //s[i]表示数组前i个元素的乘积 //t[i]表示数组后N-i个元素的乘积 //p[i] = s[i-1] * t[i+1]; //p[i]表示数组除第I个元素外,其他N-