[WXM] LeetCode 523. Continuous Subarray Sum C++

自己开发的博客网站,欢迎访问https://www.weiboke.online
#523. Continuous Subarray Sum
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:

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

##Approach

  1. 题目大意就是找连续子数组的和是k的倍数,倍数是包括零的。这道题很容易可以想到用前缀和解决,我们统计一遍前缀和,然后遍历每个数的前缀和,就可以解决,可是效率不高,因为是O(n^2),然后我看了一下别人的提交的代码,还可以用一种O(n)的方法,我们可以不断相加,中间不断取余,如果中间发现有余数相等,说明就一定存在答案,因为suma%k=(suma+sumb)%k,所以sumb%k=0。
    ##Code
    O(n^2)
class Solution {
public:
	bool checkSubarraySum(vector& nums, int k) {
		int n = nums.size();
		if (n == 0)return false;
		vectordp(n, 0);
		dp[0] = nums[0];
		for (int i = 1; i < n; i++) {
			dp[i] = dp[i - 1] + nums[i];
		}
		for (int i = 1; i < n; i++) {
			for (int j = 0; j < i; j++) {
				int ans;
				if (j == 0) {
					ans = dp[i];
				}
				else {
					ans = dp[i] - dp[j - 1];
				}
				if (ans==0||(k!=0&&ans % k==0))return true;
			}
		}
		return false;
	}
};

O(n)

class Solution {
public:
	bool checkSubarraySum(vector& nums, int k) {
		unordered_setunst;
		int pre = 0, sum = 0;
		for (const int&i : nums) {
			sum += i;
			int res = (k == 0 ? sum : sum%k);
			if (unst.find(res) != unst.end())return true;
			unst.insert(pre);
			pre = res;
		}
		return false;
	}
};

你可能感兴趣的:([WXM] LeetCode 523. Continuous Subarray Sum C++)