【题目】
给定一个无序数组arr,其中元素可正、可负、可 0,给定一个整数k。求arr所有子数组中累加和为k的最长子数组长度。
【补充问题】
给定一个无序数组arr,其中元素可正、可负、可 0。求arr所有子数组中正数与负数个数相同的最长子数组长度。
【补充问题】
给定一个无序数组arr,其中元素只是 1 或 0。求arr所有的子数组中 0 和 1 个数相等的最长数组长度。
【基本思路】
原问题。使用一个哈希表map,记录每一个累加和情况出现的位置,相同的累加和只记录出现最早的位置。
从左到右遍历数组,假设遍历到位置 i,记录 arr[0…i] 的累加和 sum,如果该累加和不存在于map中,将该 sum 作为 key, i 作为 value 添加到map中;否则不进行添加。接下来判断 sum - k 这个累加和是否存在与map中,如果存在的话,假设位置记为 index,那么可想而知,i - index 其实就是一个累加和为k的子数组长度。使用一个全局变量保存遍历到的最长子数组长度。继续遍历数组按照上述方法寻找其他的累加和为k的子数组。
这里我们试着考虑一个情况,假设我们遍历到位置 i,发现此时累加和为k,很显然,这满足题意,arr[0…i] 就是一个累加和为 k 的子数组,但是我们发现,如果我们按照上述方法在map中寻找 sum - k 的元素,也就是 0,map 中是不会有 0 这个元素的,所以最终这个子数组会被忽略。所以在这里强调很重要的一点:map初始的时候必须要添加一个key = 0、value = -1 的键值对,这样可以避免以位置 0 开头的子数组的丢失。
【代码实现】
#python3.5
def maxLength(arr, k):
if arr == None or len(arr) == 0:
return 0
map = {}
map[0] = -1
sum = 0
length = 0
for i in range(len(arr)):
sum += arr[i]
if sum not in map:
map[sum] = i
if sum - k in map:
length = max(length, i - map[sum-k])
return length
对于补充问题其实就是原问题的简单变形。第一个补充问题,只要将所有的正数变成为 1,所有的负数变成为 -1,只要找到数组中累加和为 0 的最长子数组长度即可。对于补充问题二,将所有的 0 变成为 -1,只要找到数组中累加和为 0 的最长子数组长度即可。代码略。