和可被 K 整除的子数组
给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续、非空)子数组的数目。
示例:
输入:A = [4,5,0,-2,-3,1], K = 5
输出:7
解释:
有 7 个子数组满足其元素之和可被 K = 5 整除:
[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]
提示:
1 <= A.length <= 30000
-10000 <= A[i] <= 10000
2 <= K <= 10000
note:注意这里的连续非空,意味着[]、[5,-2,-3]是不允许的!
1、暴力解法
#include <iostream> #include <vector> #include <unordered_map> using namespace std; class Solution { public: int subarraysDivByK(vector<int> &A, int K) { int ans = 0; for (int i = 0; i < A.size(); ++i) { int add = 0; for (int j = i; j < A.size(); ++j) { add += A[j]; if (add % K == 0) ans += 1; } } return ans; } }; int main() { vector<int> nums{4, 5, 0, -2, -3, 1}; Solution s; cout << s.subarraysDivByK(nums, 5) << endl; }
2、排列组合(前缀和,哈希表)
#include <iostream> #include <vector> #include <unordered_map> using namespace std; class Solution { public: int subarraysDivByK(vector<int> &A, int K) { unordered_map<int, int> ans = {{0, 1}}; int add = 0; for (int i = 1; i < A.size() + 1; ++i) { add += A[i - 1]; add %= K; ans[((add + K) % K)] += 1; } int res = 0; for (auto ele:ans) { int val = ele.second - 1; res += (1 + val) * val / 2; } return res; } }; int main() { vector<int> nums{4, 5, 0, -2, -3, 1}; Solution s; cout << s.subarraysDivByK(nums, 5) << endl; }
浙公网安备 33010602011771号