classSolution { public: intsubarraysDivByK(vector<int>& A, int K){ unordered_map<int, int> table; table.insert({0, 1}); int sum = 0, ans = 0; for (int i = 0; i < A.size(); i++) { sum += A[i]; auto iter = table.begin(); while (iter != table.end()) { if ((sum - iter->first) % K == 0) ans += iter->second; iter++; } if (table.find(sum) != table.end()) table.find(sum)->second++; else table.insert({sum, 1}); } return ans; } };
解法二(取余)
其实两道题确实有关联,都是前缀和的题目,不过用hash表来记录前缀和的方法不适合这道题。
考虑到如果两个前缀和对 K 进行取余的结果相等,则这两个前缀和之间的元素和可以被 K 整除,由于我们可以用大小为K的数组去记录所有前缀和的余数分布,然后累加起来得到最终结果。
取余公式:(x % K + K) % K
还要记得额外处理前缀和对 K 取余为0的情况。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
classSolution { public: intsubarraysDivByK(vector<int>& A, int K){ vector<int> count(K); int sum = 0; for (int i = 0; i < A.size(); i++) { sum += A[i]; count[(sum % K + K) % K]++; } int ans = count[0]; for (int i = 0; i < K; i++) { ans += count[i] * (count[i] - 1) / 2; } return ans; } };