题目链接:1590. 使数组和能被 P 整除
方法:前缀和 + 哈希
解题思路
(1)要求\((sum - sunSum)\) % \(p = 0\),即要求 \([sum - (s[j] - s[i])]\) % \(p = 0\), 即 \(sum\) % \(p = (s[j] - s[i])\) % \(p\),即 \(s[j]\) % \(p - sum\) % \(p = s[i]\) % \(p\);
(2)上述中的\(sum\)可以提前确定下来,\(s[j]\)为当前的前缀和,即要寻找之前计算过的前缀和中是否有\(s[i]\),之前计算过的前缀和被存入\(idx\)中。
代码
class Solution {
public:
int minSubarray(vector<int>& nums, int p) {
int x = 0;
for (auto &num : nums) x = (x + num) % p;
int ans = nums.size(), s = 0;
unordered_map<int, int> idx{{s, -1}};
for (int i = 0; i < nums.size(); i ++ ) {
s = (s + nums[i]) % p;
idx[s] = i; // 保证s的值为当前最靠近右端的下标,保证区间最小
auto it = idx.find((s - x + p) % p);
if (it != idx.end()) ans = min(ans, i - it->second);
}
return ans == nums.size() ? -1 : ans;
}
};
复杂度分析
时间复杂度:\(O(n)\);
空间复杂度:\(O(n)\)。