未排序数组中累加和为给定值的最长子数组
2016-01-17 15:36
204 查看
注意数组元素可正可负,给定值设为k,求其和为K的最长子数组长度
解法1:
最笨的方法,穷举所有子数组,每次穷举到特定子数组时候,把子数组元素都加起来,设立length,然后维持该length,时间复杂度O(N^3)
解法2:
使用前缀和数组,比如数组a[10],设置help数组,help[i]代表a[0]+a[1]+```+a[i],这样,在穷举到某个特定数组时候,假设该区间左端为i,右端为j,则不用再麻烦的去累加,直接计算help[j]-help[i]-1就可以啦 时间复杂度为O(n^2)
解法3:
根据第二种解法,我们可以考虑使用hash表,怎么用呢?
首先我们可以把穷举子数组(O(n^2)复杂度)简化,比如对于元素a[i],我们可以找以a[i]为结尾的最长子数组,找以a[i+1]为结尾的最长子数组, 比较n次,就可以找到啦。
其次,我们如何找以a[i]为结尾的最长子数组呢,最笨的办法好像还是从头开始,穷举,a[0]````a[i] a[1]````a[i] a[2]`````a[i],这样看来好像和方法2没什么多大的进步,但是其实这个过程是可以用O(1)解决的,怎么解决,那就是哈希表喽
我们先遍历一个元素时候,会得出一个值sum,这个值得含义是从a【0】加到该元素,我们先设想有该元素,然后我们可以知道,哦哦,既然加到现在是sum,那么如果后面某一段值为k,前一段值为sum-k,并且我们知道了sum-k的长度,我们岂不可以得知和为k这一段的长度啦?于是乎我们就找,在哈希表中是否有key为sum-k,值为index下标的元素,如果有,那证明大功告成,因为哈希表中存储key,肯定代表是“从左边开始第一次加到key”,而不会是再加5,再加-5这样的又变成key这样的情况,这样,既然我们保证了加到sum-k的区间长度最短,就可以保障后面和为k的区间长度最长,维持一个len变量就可以了。
解法1:
最笨的方法,穷举所有子数组,每次穷举到特定子数组时候,把子数组元素都加起来,设立length,然后维持该length,时间复杂度O(N^3)
解法2:
使用前缀和数组,比如数组a[10],设置help数组,help[i]代表a[0]+a[1]+```+a[i],这样,在穷举到某个特定数组时候,假设该区间左端为i,右端为j,则不用再麻烦的去累加,直接计算help[j]-help[i]-1就可以啦 时间复杂度为O(n^2)
解法3:
根据第二种解法,我们可以考虑使用hash表,怎么用呢?
首先我们可以把穷举子数组(O(n^2)复杂度)简化,比如对于元素a[i],我们可以找以a[i]为结尾的最长子数组,找以a[i+1]为结尾的最长子数组, 比较n次,就可以找到啦。
其次,我们如何找以a[i]为结尾的最长子数组呢,最笨的办法好像还是从头开始,穷举,a[0]````a[i] a[1]````a[i] a[2]`````a[i],这样看来好像和方法2没什么多大的进步,但是其实这个过程是可以用O(1)解决的,怎么解决,那就是哈希表喽
我们先遍历一个元素时候,会得出一个值sum,这个值得含义是从a【0】加到该元素,我们先设想有该元素,然后我们可以知道,哦哦,既然加到现在是sum,那么如果后面某一段值为k,前一段值为sum-k,并且我们知道了sum-k的长度,我们岂不可以得知和为k这一段的长度啦?于是乎我们就找,在哈希表中是否有key为sum-k,值为index下标的元素,如果有,那证明大功告成,因为哈希表中存储key,肯定代表是“从左边开始第一次加到key”,而不会是再加5,再加-5这样的又变成key这样的情况,这样,既然我们保证了加到sum-k的区间长度最短,就可以保障后面和为k的区间长度最长,维持一个len变量就可以了。
#include<iostream> #include <hash_map> #include <algorithm> using namespace std; //给定一个无序数组,并给定k值,找出其中最长的和等于k的子数组,输出其长度 注意,数组元素可正可负 //要求空间复杂度为O(n),时间复杂度为O(n) int a[]={1,2,3,3}; int k=6; int findArray(int len) { int ret=0; int i,sum=0; hash_map<int,int> mymap; mymap[0]=-1; for(i=0;i<len;i++) { sum+=a[i]; if(mymap.find(sum-k)!=mymap.end()) { ret=max(ret,i-mymap.find(sum-k)->second); } else { mymap[sum]=i; } } return ret; } int main() { cout<<findArray(4)<<endl; return 0; }
相关文章推荐
- 使用Python Pandas处理亿级数据
- Android源码学习之二-Activity如何管理对话框
- DateUtil
- mysql概要(十三)备份和恢复
- imagenet原图片下载地址
- 如何将两个有重复字符在内的字符串合并成一个,并且排序
- 购物车案例——麻雀虽小五脏俱全(小标签 浮动 定位……)
- 【CODEVS1219】骑士游历
- 安装pip ---python windows
- 查询sql server 2008所有表和行数
- 如何关闭浏览器输入框自动补齐
- HDU 1074 Doing Homework (状压dp)
- Android学习笔记-使用layout方法使View随手指的滑动而滑动
- iOS网络-NSURLSessionTask简单介绍
- 批处理管理文件以及文件夹
- RHEL 6.2配置本地yum源
- Android 四大组件之BroadcastReceiver
- 静态顺序表
- CentOS笔记——配置DNS服务器
- CentOS笔记——配置DNS服务器