和为 K 的子数组的思路探讨与源码
和为 K 的子数组的题目如下图,该题属于数组和哈希表类型的题目,主要考察对于数组和哈希表的使用和理解。本文的题目作者想到2种方法,分别是枚举方法和哈希表方法,其中枚举方法使用java进行编写,而哈希表方法使用Python进行编写,当然这可能不是最优的解法,还希望各位大佬给出更快的算法。
本人认为该题目可以使用直接枚举的方法,首先初始化参数,计数个数默认为0并且求得数组的长度。然后开始遍历数组,在数组的内部用sum表示求和结果,即在0到当前位置的数组里进行遍历,去计算求和的结果是否等于k的值,如果相等则可以将计数个数加1,如果不相等就跳过,直到遍历结束并返回计数个数结果。那么按照这个思路我们的Java代码如下:
#喷火龙与水箭龟
public class Solution {
public int subarraySum(int[] nums, int k) {
int countNum = 0;
int lenNum = nums.length;
for (int jr = 0; jr < lenNum;jr++) {
int sum = 0;
for (int kr = jr; kr >= 0;kr--) {
sum=sum+nums[kr];
if (sum == k) {
countNum = countNum+1;
}
}
}
return countNum;
}
}
显然,我们看到枚举法的效率非常一般,所以还可以使用哈希表的方法进行处理,首先我们初始化计数个数、字典、数组长度等参数。然后开始遍历数组,用前缀和的值保存当前数组的结果,并且计算和k值还差多少,如果前缀和与k是相等,也就是差值是0的时候,就把计数个数加1,否则就跳过。并且再次更新计数的个数,如果字典里有这个差值则获取差值对应的VALUE值,如果没有则不进行更新;并且再把前缀的值保存到字典里,按照这个思路直到遍历结束,下面是Python代码部分:
#喷火龙与水箭龟
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
countNum=0
preNum=0;
dictMap={}
numLen=len(nums)
for jr in range(numLen):
preNum=preNum+nums[jr]
diffNum=preNum-k
if(preNum==k):
countNum=countNum+1
countNum=countNum+dictMap.get(diffNum,0)
dictMap[preNum]=dictMap.get(preNum,0)+1
return countNum
从结果来说java版本的枚举方法的效率比较一般,而python版本的哈希表方法的速度不错,但应该是有更多的方法可以进一步提速的,希望朋友们能够多多指教,非常感谢。