Continuous Subarray Sum
2017-02-26 16:50
169 查看
leetcode第523题,竞赛题,要求在一组非负的整数中找出一个长度大于2的连续的子序列,使之加和可以等于目标数的倍数。
这个题简单的想法就是把所有子序列找出求个和,然后判断,这显然是一种暴力的办法,而且效率很低,假设有n个数字,那么所有可能就有n(n-1)/2个,再加上求和操作,复杂度接近o(n^3),显然是不行的。
如果想在线性时间内解决,就意味着只能扫一遍这个数组,也就意味着你只能求出从头开始的前缀和的大小。那怎么利用这个前缀和来解决子数组的问题呢,因为子数组并不一定是从原数组开头算起的。
这里利用了这样的技巧,求出前缀和,对目标数取模,维护一个字典或者hash表的结构,存储这个模值和对应的索引号,然后把这个模值作为加和继续累加后面的数字,假设加到某一个数字的时候,取模发现字典中已有这个数值,则说明在累加过程中,已经正好加了一个目标数的倍数,而这一段就可以凑出目标数的倍数。再用索引号判断这一段的长度是否大于2就可以了。
另外,还要注意数组中全0,目标数也是0的情况就可以了。
这个题简单的想法就是把所有子序列找出求个和,然后判断,这显然是一种暴力的办法,而且效率很低,假设有n个数字,那么所有可能就有n(n-1)/2个,再加上求和操作,复杂度接近o(n^3),显然是不行的。
如果想在线性时间内解决,就意味着只能扫一遍这个数组,也就意味着你只能求出从头开始的前缀和的大小。那怎么利用这个前缀和来解决子数组的问题呢,因为子数组并不一定是从原数组开头算起的。
这里利用了这样的技巧,求出前缀和,对目标数取模,维护一个字典或者hash表的结构,存储这个模值和对应的索引号,然后把这个模值作为加和继续累加后面的数字,假设加到某一个数字的时候,取模发现字典中已有这个数值,则说明在累加过程中,已经正好加了一个目标数的倍数,而这一段就可以凑出目标数的倍数。再用索引号判断这一段的长度是否大于2就可以了。
另外,还要注意数组中全0,目标数也是0的情况就可以了。
class Solution(object): def checkSubarraySum(self, nums, k): """ :type nums: List[int] :type k: int :rtype: bool """ n = len(nums) sumNum = 0 mod = {} mod[0] = -1 for i in range(n): sumNum += nums[i] if k != 0: sumNum %= k if sumNum in mod: if i-mod[sumNum] > 1: return True else: mod[sumNum] = i else: if sumNum == 0 and i >= 1: return True return False
相关文章推荐
- LeetCode 523: Continuous Subarray Sum
- 523-Continuous Subarray Sum
- lintcode:Continuous Subarray Sum
- [LintCode] Continuous Subarray Sum II
- LeetCode 523 Continuous Subarray Sum (同余)
- 算法15 Continuous Subarray Sum
- LintCode 402: Continuous Subarray Sum
- 题解:Continuous Subarray Sum
- 523. Continuous Subarray Sum
- [LeetCode OJ]Continuous Subarray Sum
- 523. Continuous Subarray Sum
- 算法训练:Continuous Subarray Sum
- lintcode-medium-Continuous Subarray Sum
- LintCode "Continuous Subarray Sum II"
- 523. Continuous Subarray Sum
- [LintCode] Continuous Subarray Sum 连续子数组之和
- Continuous Subarray Sum
- [LeetCode] Continuous Subarray Sum 连续的子数组之和
- 【LeetCode523】. Continuous Subarray Sum
- [LeetCode] Continuous Subarray Sum