和最接近0的子序列

给定整数m,n和数组x[n],找出某个i,使得x[i]+x[i+1]+x[i+2]+x[i+3]+x[i+4]…x[i+m]最接近于零。

(0<=i<n-m)

一.暴力解法

遍历各个i值,计算子序列的和,然后求出最接近0的

int find(int a[],int n,int m)     //寻找m+1个数字,使得他们的和最小
{
	int i=0;
	int thissum=0;
	int j=0;
	int ans=INT_MAX;
	for(i=0;i<n-m;i++)         //时间复杂度为O(m*n)
	{
		thissum=0;
	for(j=i;j<=i+m;j++)
		thissum+=a[j];
	if(abs((int)(thissum))<abs((int)(ans)))
		ans=abs((int)thissum);
	}
	return ans;
}

显然,时间复杂度为O(m*n),空间复杂度为O(1)

二.动态规划:

建立数组dp[],dp[i]存放的是x[i]+x[i+1]+…x[i+m]的值,则递推关系式为:

dp[i+1]=dp[i]-a[i]+a[i+1+m],然后遍历dp[]数组,求出最近于零的。

int find2(int a[],int n,int m)
{
int *dp=(int *)malloc(n*sizeof(int));
int i=0;
int tmp=0;
for(i=0;i<=m;i++)
{
	tmp+=a[i];
}
dp[0]=tmp;
for(i=1;i<n-m;i++)
{
dp[i]=dp[i-1]+a[i+m]-a[i-1];
}
int ans=INT_MAX;
for(i=0;i<n;i++)
{
	if(abs((int)dp[i])<ans)
		ans=abs((int)dp[i]);
}
return ans;
}

时间复杂度为O(n),空间复杂度为O(n)

还可以对上面的代码稍作改进,上面的dp[]数组,只要用一个变量即可。

int find3(int a[],int n,int m)
{
int tmp=0;
int ans=INT_MAX;
int i=0;
for(i=0;i<=m;i++)
	tmp+=a[i];
if(abs((int)tmp)<ans)
	ans=abs((int)tmp);
for(i=1;i<n-m;i++)
{
	tmp=tmp-a[i-1]+a[i+m];
	if(abs((int)tmp)<ans)
		ans=abs((int)tmp);
}
return ans;
}

时间复杂度为O(n),空间复杂度为O(1)

完整代码为:

# include <iostream>
# include <cstdlib>
# include <cmath>
# include <ctype.h>
using namespace std;

int find(int a[],int n,int m)     //寻找m+1个数字,使得他们的和最小
{
	int i=0;
	int thissum=0;
	int j=0;
	int ans=INT_MAX;
	for(i=0;i<n-m;i++)         //时间复杂度为O(m*n)
	{
		thissum=0;
	for(j=i;j<=i+m;j++)
		thissum+=a[j];
	if(abs((int)(thissum))<abs((int)(ans)))
		ans=abs((int)thissum);
	}
	return ans;
}

int find2(int a[],int n,int m)
{
int *dp=(int *)malloc(n*sizeof(int));
int i=0;
int tmp=0;
for(i=0;i<=m;i++)
{
	tmp+=a[i];
}
dp[0]=tmp;
for(i=1;i<n-m;i++)
{
dp[i]=dp[i-1]+a[i+m]-a[i-1];
}
int ans=INT_MAX;
for(i=0;i<n;i++)
{
	if(abs((int)dp[i])<ans)
		ans=abs((int)dp[i]);
}
return ans;
}

int find3(int a[],int n,int m)   //
{
int tmp=0;
int ans=INT_MAX;
int i=0;
for(i=0;i<=m;i++)
	tmp+=a[i];
if(abs((int)tmp)<ans)
	ans=abs((int)tmp);
for(i=1;i<n-m;i++)
{
	tmp=tmp-a[i-1]+a[i+m];
	if(abs((int)tmp)<ans)
		ans=abs((int)tmp);
}
return ans;
}

int main()
{
	int a[10]={1,-2,3,-4,-5,-6,7,8,9,0};
	cout<<find(a,10,3)<<endl;
	cout<<find2(a,10,3)<<endl;
	cout<<find3(a,10,3)<<endl;
system("pause");
return 0;
}

和最接近0的子序列

时间: 2025-01-17 08:58:59

和最接近0的子序列的相关文章

2015美团校招部分笔试题

美团笔试全部都是算法题,一共8题,前面4道想对偏简单,后面4道偏难,前面4题就不贴出来了,大部分都会,下面给出后面四题的题目. 求斜率最大值:平面上N个点,每两个点都确定一条直线,求出斜率最大的那条直线所通过的两个点(斜率不存在的情况不考虑).时间效率越高越好.已知了一个排序算法. 提示:假设有(Ax,Ay).(Bx, By)两点(不相邻)画出的直线斜率为K,则点(Cx, Cy)(在AB之间Cx > Ax, Cx < Bx)则ABC三点组成三角形(若组成不了三角形说明在一条直线上)则直线AC或

为什么Fibonacci数列相邻两项之比会趋于0.618

转帖: http://www.matrix67.com/blog/archives/5221 你或许熟知一个非常经典的结论: Fibonacci 数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, … (头两项都是 1 ,此后每一项都是前两项之和)的相邻两项之比将会越来越接近黄金比例 0.618 ,不信请看: 1 / 1 = 1.0000000... 1 / 2 = 0.50000000... 2 / 3 = 0.66666667... 3 / 5 = 0.60000000

动态规划---最长上升子序列问题(O(nlogn),O(n^2))

LIS(Longest Increasing Subsequence)最长上升子序列 或者 最长不下降子序列.很基础的题目,有两种算法,复杂度分别为O(n*logn)和O(n^2) . ********************************************************************************* 先回顾经典的O(n^2)的动态规划算法: 设a[t]表示序列中的第t个数,dp[t]表示从1到t这一段中以t结尾的最长上升子序列的长度,初始时设dp[

子数组和最接近零问题

子数组和最接近零问题: 对于长度为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 ******************************

0代码隐藏GroupedTableView上边多余的间隔

0代码隐藏GroupedTableView上边多余的间隔 实现诸如支付宝的 “探索” 页面时,最简单的方案是在 Storyboard 中来一个静态 Grouped UITableViewController,把各个 Cell 中的元素摆好就行了 不过会有下面的问题,第一个 Section 距离屏幕顶端有间隔 一行代码搞定 研究发现,这里其实是一个被 UITableView 默认填充的 HeaderView.而且,当试图将它的高度设置为 0 时,完全不起效果.但我们用下面的代码创建一个高度特别小的

最长递增子序列 &amp;&amp; 最大子序列、最长递增子序列、最长公共子串、最长公共子序列、字符串编辑距离

http://www.cppblog.com/mysileng/archive/2012/11/30/195841.html 最长递增子序列问题:在一列数中寻找一些数,这些数满足:任意两个数a[i]和a[j],若i<j,必有a[i]<a[j],这样最长的子序列称为最长递增子序列. 设dp[i]表示以i为结尾的最长递增子序列的长度,则状态转移方程为: dp[i] = max{dp[j]+1}, 1<=j<i,a[j]<a[i]. 这样简单的复杂度为O(n^2),其实还有更好的方

任意区间的最长连续递增子序列,最大连续子序列和

hdu3308 给n个数,有m个操作 U a b 表示将第a个数改成b Q a b 表示询问区间[a,b]的最长连续递增子序列. 区间询问问题且带修改,一般是用线段树来解决 那么要维护 Llen[rt], Lval[rt][2] 表示rt所对应的区间[l,r] 以l开头的最长连续递增子序列的长度, Lval[rt][0]表示子序列的最左边的值,Lval[rt][1]表示子序列最右边的值 Rlen[rt],Rval[rt][2]  表示rt所对应的区间[l,r]以r结尾的最长连续递增子序列的长度,

算法-最大连续子序列和

题目:给定(可能是负的)整数A1.A2.….AN,求出并确定对应的序列的最大值.如果所有的整数都是负数,那么最大连续子数列和就是0,只是求出最大值,不需要求出具体的序列,作为这个题目的变种有很多情况下给你一个确定的数列,具体求和,大同小异,共有四种解法,按照时间复杂度来解,object-c实现,解法如下: 穷举法 这个应该是这个题目最容易想到的方式,通过循环遍历出所有的序列组合,求出最大的序列的最大值,代码如下: -(NSInteger)maxSubsequenceSum:(NSArray *)

最大子序列和算法分析&mdash;&mdash;好的算法对于编程是多么重要!!!

昨天晚上在宿舍看Mark Allen Weiss老爷子的<数据结构与算法分析Java语言描述>的这本书,看到第二章的时候举了个例子来讨论,就是关于最大子序列和的算法分析.一共提了四个算法,首先当你看见第一个算法的时候觉得这个算法不错,可以实现,再接着当你看到后面连着的三个例子的时候这才明白算法一步步的优化对于整个性能的提升,有时候我们不是想不出来好的算法,只是当第一种算法出来得时候我们的思维已经被局限化了,觉得是对的就以为是唯一解了,实感唏嘘! 早上来到实验室特地找了一些资料,贴在这里,以后多