这次的题目如图所示:
这道题一看我的第一反应就是存储加和结果来计数,然后根据题目下方给的提示,我创建了一个二维表来存储加和结果。
提示为:
sum(i,j)=sum(0,j)-sum(0,i), where sum(i,j) represents the sum of all the elements from index i to j-1. Can we use this property to optimize it.
sum(0,j)表示的就是nums前j和数字之和,sums(i,j)就是nums中从第i+1个数字之和到第j个数字之和。
利用这个性质,我创建了一个二维表来进行尝试:
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
lens = len(nums)
store = [[0.5 for i in range(lens)] for j in range(lens+1)]
store[0][0] = nums[0]
for i in range(1,lens):
store[0][i] = store[0][i-1] + nums[i]
for i in range(lens):
for j in range(i+1,lens):
store[i+1][j] = store[0][j] - store[0][i]
print(store)
return sum([store[i].count(k) for i in range(lens)])
但是这种方法在面对最后那个超长的测试用例时超时了,这个我也是有预计的,因为leetcode总是会有一些十分极端的测试案例出现。
还有一个类似的方法,就是不构建数组存储结果,直接对等于k的结果计数,但是也超时了。
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
lens = len(nums)
store = [0 for i in range(lens)]
count = 0
for i in range(lens):
store[i] = store[i-1] + nums[i]
if store[i] == k:
count += 1
for i in range(lens):
for j in range(i+1,lens):
if store[j] - store[i] == k:
count += 1
return count
但是除了这个方法以外,我也没有想到有什么特别好的方法了,因为我觉得需要考虑到所有可能的加和结果,可能还是需要一个遍历的过程。于是我就直奔评论区。
先说一点,我在评论区见到了直接用我这种方法的答案,但是人家用的是C++,跟我的python还是有本质上的速度区别,难顶。
而评论区里面提到最多的方法就是使用哈希表来计数,那最方便的方法就是用字典来实现了。
参考评论区大佬们的解答,我也用python自己写了一下:
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
#通过字典来存储内容
sums = 0
result = 0
#count这个表是用来存储满足条件(加和=k)的和的计数情况的
count = {}
count[0] = 1
for i in range(len(nums)):
sums += nums[i]
#这里在判断这个key是否在计数字典中
#如果此前sums - k被记过数,那说明sums-k的值就是其中一段从0开始的连续数组的和
#那么说明中间有一段连续数组的加和结果是k,那就可以把这段数字的加和计数加上去
if sums - k in count:
result += count[sums - k]
if sums not in count:
count[sums] = 0
count[sums] += 1
return result
其中有一个遍历,其中sums用来记录每一步遍历的前i个元素的加和结果,result用来对记录符合k的项目计数,count用来对sums的出现次数计数。
result加上的计数项是从count里面来的,代码里之所以用sums-k来计数,是因为如果sums-k在count中的话,说明有某一段或多段前i项和是在在count中的,那就说明从那一段结尾的下一个元素开始到现在sums计数的结尾,这一段连续数组的和是k(也有可能是多段)。这样在单个遍历过程中就把所有加过考虑到了(因为每一个和的结果都会被记录在count中)。count[0]=1的目的是把sums=k的给加进去。
用这种方法,速度就快好多好多了,提交记录结果如下所示:
写完后我有两个想法,一个遇到类似的计数或者加和的问题是要多用dict或者set这样的哈希表来解决问题,二是还真得捡起C++来用用,毕竟python速度还是慢了有点多(ˉ▽ˉ;)...