给定一个整数数组,找到和为零的子数组。你的代码应该返回满足要求的子数组的起始位置和结束位置。比如给出 [-3, 1, 2, -3, 4]
,返回[0, 2]
或者 [1, 3]
.
Lintcode上的一道题目,这一题我开始想到的是brute force的方法,求出所有子数组,并判断和是否为0。子数组一共有n*(n-1)/2个,如果每次再求和,则复杂度为O(n^3),于是想到使用DP缓存中间结果,不过无论用一维数组还是二维数组,最后都是超时的结果。所以说如果暴力解法都是多项式时间的话,则使用DP的可能性很低。所以这题得另想思路。
Hashmap感觉是解这种问题的通用套路,这题看似不可以,其实用很巧的思路转换一下就可以。如果有一段子数组和为0,比如从i到j,则第一个数到第i个数的和等于第一个数到第j个数的和的值。因为中间这段为0。所以从可以依次向后求解,并将和作为键保存到词典中,键对应的值为index i。一旦后面有求和值为字典中的键值,则前一个index+1至现在的index为该和为0的数组。但是有一种情况如果从第一个数组开始的子序列和为0,则需要如何处理?所以一个好的办法是先在字典中存入{0:-1}这一对,方便后序求解。代码如下:
class Solution: """ @param nums: A list of integers @return: A list of integers includes the index of the first number and the index of the last number """ def subarraySum(self, nums): map = {0:-1} sum = 0 for i in xrange(len(nums)): sum += nums[i] if map.has_key(sum): return [map[sum]+1,i] map[sum] = i return
原文:http://www.cnblogs.com/sherylwang/p/5554660.html