未排序数组中累加和小于给定值的最长子数组长度
2016-01-21 23:40
411 查看
本体和本博客里另外一个文章,累加和等于给定值的最长子数组,非常类似,但是上一个题目来说,为了节省时间,使用了哈希表,但是那个题目是,等于,所以哈希表里有,就直接拿,没有,就跳过了,但是本题目是要求,小于或者等于,没办法直接查找,难道要遍历哈希表吗,这样时间复杂度又上去了,所以这里给出了一个新的数组,用作辅助
一定要找到他俩的共同点,都是求所有的以a【i】为结尾的数组中,累加和小于给定值的最长子数组长度。
本题举例来说,{3,-2,-4,0,6}
如果我们要求这个数组,则首先建立sum数组,就是以a[0]开始,a[i]结尾的数组的和
sum数组为{3,1,-3,-3,3},元素sum[i]代表以arr[0]开头,arr【i】结尾的子数组的和
另外建立辅助数组help
help[i]表示已arr[0]开头,arr[i]结尾的数组中,曾经出现的最大累加和
help数组为{3,3,3,3,3}
我们可以分析如下
当累加到元素0的时候,sum为3,就是本元素,然后我们可以这样考虑,既然要寻找以arr【0】开头,arr【0】为结尾和小于等于k的最长子数组,是不是说,我们找到了以arr【0】开头,第一次和大于等于sum-k的子数组,它后面就是我们要求的呢?(为什么叫第一次,因为数组未必全是正数,有可能后面还会多次出现和大于等于sum-k这个情况),本处来说,我们就是寻找前面和大于等于3-(-2)=5这样的子数组
这时候,我们前面建立的help数组就开始发挥威力了,我们其实可以得知,help的意义在于表明累加到该处时,出现过的最大累加和,相当于维持一个max,所以这个数组是单调递增的,而既然是递增数组,我们就可以使用二分搜索,将时间复杂度将为log(n);
sum-(-2)=5,我们就开始找,好吧,help数组里没有5,代表不存在
累加到元素1的时候,sum为1,1-(-2)=3,我们开始寻找help数组中哪个位置的元素开始第一次大于等于3,明显是索引0,所以意思就是说,从arr[0]后面到arr【1】,这一段就是要求的,这一段长度为1
累加到元素2的时候,sum为-3,-3-(-2)=-1
这时候,我们要非常注意一个事情,这件事情很重要,算个特殊情况,如果我们此时得到的sum,本身就是小于k的,比如这里,sum是-3,k是-2,我们其实已经不用找了,这一段子序列本身就代表了。
所以本处则是这个特殊条件,长度为3
累加到元素3的时候,sum为-3,和上个情况类似,长度为4
累加到元素4 的时候,sum和为3,3-(-2)=5,在help数组中没有找到,代表不存在
代码如下:
一定要找到他俩的共同点,都是求所有的以a【i】为结尾的数组中,累加和小于给定值的最长子数组长度。
本题举例来说,{3,-2,-4,0,6}
如果我们要求这个数组,则首先建立sum数组,就是以a[0]开始,a[i]结尾的数组的和
sum数组为{3,1,-3,-3,3},元素sum[i]代表以arr[0]开头,arr【i】结尾的子数组的和
另外建立辅助数组help
help[i]表示已arr[0]开头,arr[i]结尾的数组中,曾经出现的最大累加和
help数组为{3,3,3,3,3}
我们可以分析如下
当累加到元素0的时候,sum为3,就是本元素,然后我们可以这样考虑,既然要寻找以arr【0】开头,arr【0】为结尾和小于等于k的最长子数组,是不是说,我们找到了以arr【0】开头,第一次和大于等于sum-k的子数组,它后面就是我们要求的呢?(为什么叫第一次,因为数组未必全是正数,有可能后面还会多次出现和大于等于sum-k这个情况),本处来说,我们就是寻找前面和大于等于3-(-2)=5这样的子数组
这时候,我们前面建立的help数组就开始发挥威力了,我们其实可以得知,help的意义在于表明累加到该处时,出现过的最大累加和,相当于维持一个max,所以这个数组是单调递增的,而既然是递增数组,我们就可以使用二分搜索,将时间复杂度将为log(n);
sum-(-2)=5,我们就开始找,好吧,help数组里没有5,代表不存在
累加到元素1的时候,sum为1,1-(-2)=3,我们开始寻找help数组中哪个位置的元素开始第一次大于等于3,明显是索引0,所以意思就是说,从arr[0]后面到arr【1】,这一段就是要求的,这一段长度为1
累加到元素2的时候,sum为-3,-3-(-2)=-1
这时候,我们要非常注意一个事情,这件事情很重要,算个特殊情况,如果我们此时得到的sum,本身就是小于k的,比如这里,sum是-3,k是-2,我们其实已经不用找了,这一段子序列本身就代表了。
所以本处则是这个特殊条件,长度为3
累加到元素3的时候,sum为-3,和上个情况类似,长度为4
累加到元素4 的时候,sum和为3,3-(-2)=5,在help数组中没有找到,代表不存在
代码如下:
#include <iostream> #include <algorithm> using namespace std; #define MAXSIZE 1010 int arr[]={3,-2,-4,0,6}; int help[MAXSIZE]; int k=-2; int len=5; //sum[i]代表以arr[0]为开头,arr[i]为结尾的子数组的和 //help[i]代表以arr[0]开头 arr[i]结尾的子数组中出现的最大累加和 int getLessestIndex(int num) { int ret=-1; int mid; int start=0,end=len-1; while(start<=end) { mid=(start+end)/2; if(help[mid]>=num) { ret=mid; end=mid-1; } else { start=mid+1; } } return ret; } int fun() { int sum=0; int i,j; int maxnum=0; int ret=0; int index; //help数组初始化 for(i=0;i<len;i++) { sum+=arr[i]; maxnum=max(maxnum,sum); help[i]=maxnum; } sum=0; for(i=0;i<len;i++) { sum+=arr[i]; if(sum<=k) { ret=max(ret,i+1); } else { index=getLessestIndex(sum-k); if(index!=-1) { ret=max(ret,i-index); } } } return ret; } int main() { //初始化help数组 cout<<fun()<<endl; return 0; }
相关文章推荐
- 商城商品购买数量增减的完美JS效果
- Sping之自动注入-1
- Spring 中的 bean
- 不同种类不同个数集合的重复排列——指数型母函数
- 普通方法,静态方法和类方法
- HTML嵌套Flash播放视频
- woj1208 Sherlock's Code
- 企业实战Shell-MySQL分库分表备份脚本 【转】
- base64加解密
- 关于UINavigationController自定义实效的问题,和自带效果研究
- UNITY 5.3.1 发行说明 中文版
- CentOS安装glibc-2.14
- 配置SSH免密码登入
- 梵高
- nginx中使用srcache_nginx模块构建缓存
- 数据类型
- Servlet实现文件上传
- [iOS] UICollectionView初始化滚动到中间的bug
- JS中Unexpected identifier错误
- 缺陷:域与静态方法