523. 连续的子数组和

<leecode 523题>
给定一个包含 非负数 的数组和一个目标 整数 k,编写一个函数来判断该数组是否含有连续的子数组,其大小至少为 2,且总和为 k 的倍数,即总和为 n*k,其中 n 也是一个整数。
示例 1:
输入:[23,2,4,6,7], k = 6
输出:True
解释:[2,4] 是一个大小为 2 的子数组,并且和为 6

解法一 : 前缀和的暴力搜索(O(n^2) )
我们遍历每一个连续的序列, 判断他是否满足条件, 我们使用前缀和(这种解法相信不用多说就会的)

public boolean checkSubarraySum(int[] nums, int k) {
		int[] presum = new int[nums.length + 1];
		presum[0] = 0;
		// 求出前i个数的前缀和
		for (int i = 1; i < presum.length; i++) {
			presum[i] = presum[i - 1] + nums[i - 1];

		}
		// 循环处理每一段连续的序列
		for(int i = 0; i < nums.length; i++){
			for(int j = i + 1; j < nums.length; j++){
				// 如果k!= 0且 中间有两个及两个以上的数组是k的倍数或者  全是零
				if((k != 0 && (presum[j + 1] - presum[i]) % k == 0) ||( presum[j + 1] - presum[i]) == k){
					return true;
				}		
			}
		}
		return false;
	}

解法二: 这个思路非常巧妙, 我们直接说明实现方式 (O(n))时间复杂度
我们用一个HashMap存储, (sum %k, index) 这里面的index是数组下标, sum表示前缀和, 到index下标的前缀和, 为什么我们需要这样处理呢?我们来看一个例子, k = 6
index 0 1 2 3 4
data 23 2 4 6 7
第一次添加进哈希表是 (23 % 6, 0), 第二次 (((23 % 6) + 2) % 6, 1), 第三次 (((((23 % 6) + 2) % 6) + 4) % 6, 2) ,我们发现第三次的key跟第一次的key冲突了, 我们就认为 从第一次道第三次时中间有 2- 0个数的子序列符合题意。 为什么呢?
加入我们在i的位置 前缀和是res, 从这个数之后有长度为n的序列满足条件, 所以到下标为i+ n 的时候 我们需要put什么呢?(((res + n * k) % k), i + n), 算出来这个key明显跟res相同, 所以中间就有n个数的序列满足题意, 当n> 1时即可

public boolean checkSubarraySum(int[] nums, int k) {

		HashMap<Integer, Integer> map = new HashMap<>();

		int sum = 0;

		map.put(0, -1); // 为了就前面两个数符合题目条件 比如[6, 0, 1,2] k = 6 
		for (int i = 0; i < nums.length; i++) {
			sum += nums[i];
			
			if (k != 0) {
				sum = sum % k;
			}

			if (map.containsKey(sum)) { // 下面的条件不满足时  我们不能选择覆盖原来的key,不然会改变长度
				if (i - map.get(sum) > 1) {
					return true;
				}
			} else {
				map.put(sum, i);
			}

		}
		return false;

	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值