523.Continuous Subarray Sum

Tags: [dp], [left_sum], [corner_case], [math], [trick]

Com: {fb}

Link: https://leetcode.com/problems/continuous-subarray-sum/#/description

Given a list of non-negative numbers and a target integer k, write a function to check if the array has a continuous subarray of size at least 2 that sums up to the multiple of k, that is, sums up to n*k where n is also an integer.

Example 1:

Input:
 [23, 2, 4, 6, 7],  k=6

Output:
 True

Explanation:
 Because [2, 4] is a continuous subarray of size 2 and sums up to 6.

Example 2:

Input:
 [23, 2, 6, 4, 7],  k=6

Output:
 True

Explanation:
 Because [23, 2, 6, 4, 7] is an continuous subarray of size 5 and sums up to 42.

Note:

  1. The length of the array won't exceed 10,000.
  2. You may assume the sum of all the numbers is in the range of a signed 32-bit integer.

Solution: Math, Trick

class Solution(object):
    def checkSubarraySum(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: bool
        """
        if not nums:
            return False

        size = len(nums)
        sum_positions = {0: -1}
        curr_sum = 0
        for i in xrange(size):
            curr_sum += nums[i]
            if k != 0:
                curr_sum %= k

            if curr_sum in sum_positions:
                pos = sum_positions[curr_sum]
                if i - pos > 1:
                    return True
            else:
                sum_positions[curr_sum] = i

        return False

Question:

  • I didn't understand this algorithm.

Solution: DP, Left Sum

class Solution(object):
    def checkSubarraySum(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: bool
        """
        if not nums:
            return False

        size = len(nums)
        left_sum = [0 for _ in xrange(size)]
        left_sum[0] = nums[0]
        for i in xrange(1, size):
            left_sum[i] = left_sum[i - 1] +  nums[i]

        for left in xrange(size - 1):
            for right in xrange(left + 1, size):
                tmp_sum = left_sum[right]
                if left - 1 >= 0:
                    tmp_sum -= left_sum[left - 1]

                if k == 0 and tmp_sum == 0:
                    return True
                elif k != 0 and tmp_sum % k == 0:
                    return True

        return False

Revelation:

  • Be careful of the cases: nums = [0, 0], k = 0, nums[1, 5], k = -6.

Note:

  • Time complexity = O(n^2), n is the number of elements of the given array.
  • Space complexity = O(n), n is the number of elements of the given array.

results matching ""

    No results matching ""