523. Continuous Subarray Sum
Problem Description:
Given a list of non-negative numbers and a target integer k, write a function to check if the array has a continuous subarray of size at least 2 that sums up to the multiple of k, that is, sums up to n*k where n is also an integer.
题解
这题有较多的corner case,特别是k=0;
1、暴力O(n^2)
对每组序列A[i],A[i+1],...,A[j-1],A[j]求和,计算其和是否能被k整除
class Solution { public boolean checkSubarraySum(int[] nums, int k) { int n = nums.length; if(k == 0) { for(int i = 0; i < n - 1; i++) { if(nums[i] == 0 && nums[i + 1] == 0) return true; } return false; } for(int i = 0; i < n; i++) { int sum = nums[i]; for(int j = i + 1; j < n; j++) { sum += nums[j]; if(sum % k == 0) return true; } } return false; } }
2、HashMap 时间复杂度 O(n)
sum[i]代表从开头当i位置的求和。该方法的思路是,若sum[i] % k == sum[j] % k 且 i > j + 1, 则存在一个子序列。
用HashMap<Integer, Integer> map, 其key为从开头位置开始到当前位置的和的mod k的值,value为当前的index。
采用此种算法要做map.put(0, -1),来应对出现sum[i] % k == 0 的情况。
class Solution { public boolean checkSubarraySum(int[] nums, int k) { int n = nums.length; Map<Integer, Integer> map = new HashMap<>(); map.put(0, -1); int runningSum = 0; for(int i = 0; i < n; i++) { runningSum += nums[i]; if(k != 0) runningSum %= k; if(map.containsKey(runningSum)) { if(i - map.get(runningSum) > 1) return true; } else map.put(runningSum, i); } return false; } }