523. 连续的子数组和
leetcode-cn.com/problems/co…
/**
* @param {number[]} nums
* @param {number} k
* @return {boolean}
*/
var checkSubarraySum = function(nums, k) {
const prefixSum = [0]
for(let i=0
prefixSum[i+1] = prefixSum[i] + nums[i]
}
for(let i=0
for(let j=i+1
const res = prefixSum[j+1] - prefixSum[i]
if(res % k ===0 || (res ===0 && k===0)){
return true
}
}
}
return false
}
- 前缀和 + 哈希
- 设位置 j < i :
- 0 到 j 的前缀和 preSum1 = 某常数1 * k + 余数1
- 0 到 i 的前缀和 preSum2 = 某常数2 * k + 余数2
- 当找到 余数1 等于 余数2时, 则 j + 1 到 i 的连续和 = preSum2 - preSum1 = (某常数2 - 某常数1) * k, 必为 k 的倍数, 返回true
/**
* @param {number[]} nums
* @param {number} k
* @return {boolean}
*/
var checkSubarraySum = function(nums, k) {
let prefixSum =0
const map = {0:-1}
for(let i=0
prefixSum = prefixSum + nums[i]
if(k !==0){
prefixSum = prefixSum % k
}
if(map[prefixSum]!==undefined){
if(i - map[prefixSum] > 1){
return true
}
}else{
map[prefixSum] = i
}
}
return false
}
560. 和为K的子数组
leetcode-cn.com/problems/su…
const subarraySum = (nums, k) => {
let count = 0
for (let i = 0
let sum = 0
for (let j = i
sum += nums[j]
if (sum == k) count++
}
}
return count
}
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
var subarraySum = function (nums, k) {
const prefixSum = [0]
let counter = 0
for (let i = 0
prefixSum[i+1] = prefixSum[i] + nums[i]
}
for(let i=0
for(let j=i
if(prefixSum[j+1] - prefixSum[i] ===k){
counter ++
}
}
}
return counter
}
- 前缀和 + 哈希
- 每个元素对应一个“前缀和”
- 遍历数组,根据当前“前缀和”,在 map 中寻找「与之相减 == k」的历史前缀和
- 当前“前缀和”与历史前缀和差分出一个子数组,该历史前缀和出现过 n 次,等价于当前项找到 n 个子数组求和等于 k。
- 遍历数组过程中,n 不断加给 count,最后返回 count
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
var subarraySum = function (nums, k) {
let prefixSum = 0
const map = new Map()
map.set(0,1)
let counter = 0
for (let i = 0
prefixSum = prefixSum + nums[i]
if(map.get(prefixSum - k)){
counter = counter + map.get(prefixSum - k)
}
const val = map.get(prefixSum)
if(val){
map.set(prefixSum,val+1)
}else{
map.set(prefixSum,1)
}
}
return counter
}