未排序数组中累加和为给定值的最长子数组系列问题
一、题目
未排序数组中累加和为给定值的最长子数组系列问题
- 给定一个无序数组 arr,其中元素可正、可负、可 0。给定一个整数 k,求 arr 所有的子数组中累加和为 k 的最长子数组长度
- 给定一个无序数组 arr,其中元素可正、可负、可 0。求 arr 所有的子数组中正数与负数个数相等的最长子数组长度
- 给定一个无序数组 arr,其中元素只是 1 和 0。求 arr 所有子数组中 0 和 1 个数相等的最长子数组长度
- 问题 2 和问题 3 都可以转换为问题 1
- 问题 2 可以把数组中正数、负数转换为 1 和 -1,然后求累加和为 0 的最长子数组长度
- 问题 3 可以把数组中的 0 转换为 -1,然后求累加和为 0 的最长子数组长度
二、思路
对于这三道题,是同样的套路,我们先推演一个公式
1 | s(i) = arr[0 ... i] |
有了这个公式,我们就可以来解决问题了。
1 | 我们假定 s(i) 为 sum,sum-k 为 s(j) |
因此我们有一个变量 sum 作为 arr[0 ... i]
子数组的累加和。有一个 map ,key 记录 sum 值,value 记录当为 sum 时,第一次出现在数组中的位置。最后一个变量 len 记录最长的子数组长度。
遍历这个数组,每次先给 sum 值加上 arr[i]
。然后从 map 中寻找是否存在 sum-k,如果存在,说明有和为 k 的子数组,并且这个子数组的下标是从 j+1 到 i 位置;更新 len 即可。然后在判断 map 中是否存在 sum ,如果不存在,则添加 (sum, i)
。如果存在,则不用管,因为我们只保存第一次出现在数组中的位置。
遍历结束,返回 len 即可。
三、代码
1 |
|