子数组和为0或者给定值的最长子数组
2015-12-04 14:17 放作夥 阅读(495) 评论(0) 编辑 收藏 举报关于数组的题目特别多,而且字符串也可以看成字符数组,进一步扩大了数组题目的量。
子数组和为0的最长子数组这道题朴素解法是O(n^2),所以这道题肯定有更优解法,否则也不会考。
一.普通的数组,即有正数有负数
考虑i<j,sum[k]定义为数组前缀和,那么如果[i,j]是所求数组,那么sum[j]-sum[i-1]=0,也就是sum[j]=sum[i-1]。那么遍历每个数组元素查一下是否前面出现过前缀和相等的元素即可,但是
这个查询每次都要从头查起,复杂度又变成了O(n^2),但假如我们用额外申请的哈希空间加速我们的查询,就能试我们的查询加速到O(1),所以整体算法复杂度O(n),另外哈希表里存的是key
为前缀和,value为元素下标。
扩展:如果不求和为0的子数组,而是任意给定值呢?
其实是大同小异的,关系式变成了sum[j]-sum[i-1]=k,也就是sum[j]=sum[i-1]+k。
二.只包含正数的数组
比起上一种数组,特殊之处是全是正数,也就是说数组前缀和之会越来越大,我们可以利用这个特性。定义两个指针left和right,分别代表所求子数组的左边界和右边界,right不停地往前遍历数组,
若left和right包含的子数组和大于给定值,那么right已经没有必要继续遍历了,因为累加和只会越来越大。因此这个时候left指针就可以也往前移动了。记录所有满足条件的子数组的最大长度,总体
时间复杂度为O(n)