560. 和为K的子数组 974. 和可被 K 整除的子数组 (哈希表)
引言
這兩道題非常相似,也是對(duì)哈希表運(yùn)用的考察,兩道題合到一起總結(jié)一下
560. 和為K的子數(shù)組
給定一個(gè)整數(shù)數(shù)組和一個(gè)整數(shù) k,你需要找到該數(shù)組中和為 k 的連續(xù)的子數(shù)組的個(gè)數(shù)。
示例 1 :
輸入:nums = [1,1,1], k = 2
輸出: 2 , [1,1] 與 [1,1] 為兩種不同的情況。
說(shuō)明 :
數(shù)組的長(zhǎng)度為 [1, 20,000]。
數(shù)組中元素的范圍是 [-1000, 1000] ,且整數(shù) k 的范圍是 [-1e7, 1e7]。
這道題就是通過(guò)逐一統(tǒng)計(jì)數(shù)組前綴和再通過(guò)哈希表的查找來(lái)確定所有子數(shù)組個(gè)數(shù);
這里只需要注意一點(diǎn)就是,前綴和本身就是k的時(shí)候需要初始化為1,就這一種情況;
注釋在代碼里,就不寫(xiě)詳細(xì)題解了,代碼如下:
class Solution { public:int subarraySum(vector<int>& nums, int k) {//key為前綴和,value為該和出現(xiàn)的次數(shù)unordered_map<int, int> hash;//前綴和為0的時(shí)候出現(xiàn)次數(shù)為一次hash[0] = 1;//如果存在pre[i] = pre[i - 1] + k;那么就可以在map里找是否存在pre[i] - k,//即map中是否存在pre[i - 1]來(lái)確定子數(shù)組個(gè)數(shù)int pre = 0, ans = 0;for (int i : nums) {pre += i;if (hash.find(pre - k) != hash.end()) {ans += hash[pre - k];}hash[pre]++;}return ans;} };974. 和可被 K 整除的子數(shù)組
給定一個(gè)整數(shù)數(shù)組 A,返回其中元素之和可被 K 整除的(連續(xù)、非空)子數(shù)組的數(shù)目。
示例:
輸入:A = [4,5,0,-2,-3,1], K = 5
輸出:7
解釋:
有 7 個(gè)子數(shù)組滿足其元素之和可被 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
這一道幾乎一模一樣,方法都一樣,無(wú)非就是上一道題的哈希表key值是差,這一道題變成模就可以了;
同樣注意初始化,當(dāng)前綴和本身被 k 整除時(shí)初始化為1即可;
額外注意一點(diǎn),c++取模時(shí)如果被除數(shù)為負(fù)數(shù)時(shí)取模結(jié)果也為負(fù)數(shù),所以為了方便運(yùn)算這里需要一個(gè)轉(zhuǎn)化,將結(jié)果轉(zhuǎn)化為正數(shù);
代碼如下:
class Solution { public:int subarraysDivByK(vector<int>& nums, int k) {unordered_map<int, int> hash;hash[0] = 1;int ans = 0, pre = 0;for (int i : nums) {pre += i;//當(dāng)被除數(shù)為負(fù)數(shù)時(shí)取模結(jié)果為負(fù)數(shù),需要改為正數(shù)int mod = (pre % k + k) % k;if (hash[mod]) {ans += hash[mod];}hash[mod]++;}return ans;} };這兩道還是需要能夠想到哈希表該怎么來(lái)用,這也是解題的關(guān)鍵;
總結(jié)
以上是生活随笔為你收集整理的560. 和为K的子数组 974. 和可被 K 整除的子数组 (哈希表)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 347. 前 K 个高频元素(哈希表)
- 下一篇: 134. 加油站(贪心算法)