Leetcode 325:和等于 k 的最长子数组长度(超详细的解法!!!)

Given an array nums and a target value k, find the maximum length of a subarray that sums to k. If there isn’t one, return 0 instead.

Example 1:

Given nums = [1, -1, 5, -2, 3], k = 3,
return 4. (because the subarray [1, -1, 5, -2] sums to 3 and is the longest)

Example 2:

Given nums = [-2, -1, 2, 1], k = 1,
return 2. (because the subarray [-1, 2] sums to 1 and is the longest)

Follow Up:

Can you do it in O(n) time?

解题思路

首先想到的做法就是建立累加和数组,和之前的问题Leetcode 303:区域和检索-数组不可变(超详细解决方案!!!)类似。先建立累加和数组,然后在计算不同区间的差值,比较差值结果是不是k,最后记录差值最大的结果即可。

from itertools import accumulate
class Solution:
    def maxSubArrayLen(self, nums, k):
        """
        :type nums: list
        :type k: int
        :rtype: int
        """
        pre_sum = [0]+list(accumulate(nums))
        res = 0
        for i in range(len(pre_sum)):
            for j in range(i, len(pre_sum)):
                if pre_sum[j] - pre_sum[i] == k:
                    res = max(res, j - i)
        return res

但是上面这种解法是O(n^2)的解法,有没有更快的?可以使用类似于Leetcode 1:两数之和(最详细解决方案!!!)中的策略,通过建立字典存储pre_sum和对应的位置i,然后计算当前累加和k的差pre_sum[i]-k,判断是不是在字典中即可,如果在的话我们就计算长度。这里有一点要注意的是,我们在记录位置i的过程中,只记录第一次出现的位置,因为我们需要求的是最大长度。

from itertools import accumulate
class Solution:
    def maxSubArrayLen(self, nums, k):
        """
        :type nums: list
        :type k: int
        :rtype: int
        """
        pre_sum = list(accumulate(nums))
        res, dic = 0, dict()

        for i in range(len(pre_sum)):
            if pre_sum[i] == k:
                res = i + 1
            elif pre_sum[i] - k in dic:
                res = max(res, i - dic[pre_sum[i] - k])
            if pre_sum[i] not in dic:
                dic[pre_sum[i]] = i

        return res

我们可以对这个代码继续优化,也就是将累加操作放到循环中去。

class Solution:
    def maxSubArrayLen(self, nums, k):
        """
        :type nums: list
        :type k: int
        :rtype: int
        """
        pre_sum, res = 0, 0
        dic = dict()

        for i in range(len(nums)):
            pre_sum += nums[i]
            if pre_sum == k:
                res = i + 1
            elif pre_sum - k in dic:
                res = max(res, i - dic[pre_sum - k])
            if pre_sum not in dic:
                dic[pre_sum] = i

        return res

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

你可能感兴趣的:(Problems,leetcode解题指南)