【Leetcode/解题报告】 560.Subarray Sum Equals K

    给出一个整数数组nums和一个整数k,问该数组中有几个连续的子串和等于k。

    解法1:没有任何优化暴力算法

    假定这个子串为[i , j],0 <= i,j < len(nums), 那么i,j共有O(n^2)种组合,求每个子串的和时间复杂度为O(n),总时间复杂度为O(n^3)。

    O(n^3)的算法当然是不可能通过的啦,代码就懒得写了。

    解法2:利用了部分和的暴力算法

    还是遍历i,j的O(n^2)种组合,每次遍历时i固定,j向前延伸,这样子串和的计算就可以用到前面计算的结果,在O(1)时间内得出子串和。

    这种算法用C++写能通过,python会超时,充分暴露python效率低下的缺点。因为我的目的是学python,C++代码就不放了。

    解法3:使用哈希表

    记下标范围[0, i)的子串和为sum(i),则下标范围[i, j) 的子串和为sum(j) - sum(i),若能找到sum(j) - sum(i) == k,则找到一个子串和等于k,再进一步,若能找到一个比j小的i使,sum(j) - k == sum(i),则找到一个符合要求的子串。那么,可以用哈希表记录有多少个比j小的i,sum(i) == sum(j) - k。

    具体做法是:声明一个字典d,key表示部分和,value表示有几个i使sum(i)等于这个部分和,遍历nums计算部分和,每次计算出一个部分和sum(j),就通过字典查看有几个比j小的i使得sum(j) - k == sum(i),即count += d[sum - k]。

    代码如下:

class Solution(object):
	def subarraySum(self, nums, k):
		"""
		:type nums: List[int]
		:type k: int
		:rtype: int
		"""
		d = dict.fromkeys([0], 1)                          # key为sum[0, i)部分和,value为sum[0, i) == key的i的数量
		sum = 0
		cnt = 0
		for i in range(0, len(nums)):
			sum += nums[i]
			if sum - k in d.keys(): cnt += d[sum - k]
			d[sum] = d.get(sum, 0) + 1
		return cnt



猜你喜欢

转载自blog.csdn.net/weixin_38196217/article/details/80053560