和为K的连续子数组
问题简述
给定一个无序数组 arr , 其中元素可正、可负、可0。给定一个整数 k ,求 arr 所有连续子数组中累加和为k的最长连续子数组长度。保证至少存在一个合法的连续子数组。
[1,2,3]的连续子数组有[1,2],[2,3],[1,2,3] ,但是[1,3]不是
要求:时间复杂度 O(n),空间复杂度 O(n)思路:前缀和+哈希表
记当前位置的前缀和为
s;利用前缀和+哈希表,可以快速判断
s - k是否存在;若存在表明有一组连续的子数组和为k;定义
book = {s: i}表示最早在i位置出现前缀和为s;比如
arr = [1,1,-1,1],其中s[1] = 0而不是3;
算法:
s = 0 # 前缀和 for i in range(N): s += arr[i] if s - k in book: if i - book[s - k] > mx_len: mx_len = i - book[s - k] if s not in book: # 记录前缀和的最早位置 book[s] = iTips:
初始化
book时加入book[0] = -1兼容sum(arr[0:i]) == k的情况;比如
arr = [1,2,3,6], k = 6,遍历到 3 时,book[6] = 2,此时book[6-6] = book[0] = -1存在,更新最大长度为2 - (-1) = 3
Last updated